Main Content

Qualify Mock Object Interaction

When you create a mock, you create an associated behavior object that controls mock behavior. Use this object to access intercepted messages sent from the component under test to the mock object (a process known as spying). For more information on creating a mock, see Create Mock Object.

In the mocking framework, qualifications are functions used to test interactions with the object. There are four types of qualifications:

  • Verifications — Produce and record failures without throwing an exception. Since verifications do not throw exceptions, all test content runs to completion even when verification failures occur. Typically verifications are the primary qualifications for a unit test since they typically do not require an early exit from the test. Use other qualification types to test for violation of preconditions or incorrect test setup.

  • Assumptions — Ensure that the test environment meets preconditions that otherwise do not result in a test failure. Assumption failures result in filtered tests, and the testing framework marks the tests as Incomplete.

  • Assertions — Ensure that a failure condition invalidates the remainder of the current test content, but does not prevent proper execution of subsequent test methods. A failure at the assertion point marks the current test method as failed and incomplete.

  • Fatal Assertions — Abort the test session upon failure. These qualifications are useful when the failure mode is so fundamental that there is no point in continuing testing. These qualifications are also useful when fixture teardown does not restore the MATLAB® state correctly and it is preferable to abort testing and start a fresh session.

The mock object is an implementation of the abstract methods and properties of the interface specified by a superclass. You can also construct a mock without a superclass, in which case the mock has an implicit interface. Create a mock with an implicit interface for a dice class. The interface includes Color and NumSides properties and a roll method that accepts a number of dice and returns a value. While the interface is not currently implemented, you can create a mock with it.

testCase = matlab.mock.TestCase.forInteractiveUse;
[mock,behaviorObj] = testCase.createMock('AddedProperties', ...
    {'NumSides','Color'},'AddedMethods',{'roll'});

Qualify Mock Method Interaction

Since the mock records interactions sent to it, you can qualify that a mock method was called. Roll one die.

val = mock.roll(1);

Verify that the roll method was called with 1 die.

testCase.verifyCalled(behaviorObj.roll(1))
Interactive verification passed.

Verify that the roll method was called with 3 dice. This test fails.

testCase.verifyCalled(behaviorObj.roll(3), ...
    'roll method should have been called with input 3.')
Interactive verification failed.

----------------
Test Diagnostic:
----------------
roll method should have been called with input 3.

---------------------
Framework Diagnostic:
---------------------
verifyCalled failed.
--> Method 'roll' was not called with the specified signature.
--> Observed method call(s) with any signature:
        out = roll([1×1 matlab.mock.classes.Mock], 1)

Specified method call:
    MethodCallBehavior
        [...] = roll(<Mock>, 3)

Verify that the roll method was not called with 2 dice.

testCase.verifyNotCalled(behaviorObj.roll(2))
Interactive verification passed.

Since the withAnyInputs, withExactInputs, and withNargout methods of the MethodCallBehavior class return MethodCallBehavior objects, you can use them in qualifications. Verify that the roll method was called at least once with any inputs.

testCase.verifyCalled(withAnyInputs(behaviorObj.roll))
Interactive verification passed.

Verify that the roll method was not called with 2 outputs and any inputs.

testCase.verifyNotCalled(withNargout(2,withAnyInputs(behaviorObj.roll)))
Interactive verification passed.

Qualify Mock Property Interaction

Similar to method calls, the mock records property set and access operations. Set the color of the dice.

mock.Color = "red"
mock = 

  Mock with properties:

    NumSides: []
       Color: "red"

Verify that the color was set.

testCase.verifySet(behaviorObj.Color)
Interactive verification passed.

Verify the color was accessed. This test passes because there is an implicit property access when MATLAB displays the object.

testCase.verifyAccessed(behaviorObj.Color)
Interactive verification passed.

Assert that the number of sides was not set.

testCase.assertNotSet(behaviorObj.NumSides)
Interactive assertion passed.

Use Mock Object Constraints

The matlab.mock.TestCase methods are convenient for spying on mock interactions. However, there is more functionality when you use a class in the matlab.mock.constraints namespace instead. To use a constraint, pass the behavior object and constraint to the verifyThat, assumeThat, assertThat or fatalAssertThat method.

Create a new mock object.

testCase = matlab.mock.TestCase.forInteractiveUse;
[mock,behaviorObj] = testCase.createMock('AddedProperties', ...
    {'NumSides','Color'},'AddedMethods',{'roll'});

Roll 2 dice. Then use a constraint to verify that the roll method was called at least once with two dice.

val = mock.roll(2);

import matlab.mock.constraints.WasCalled
testCase.verifyThat(behaviorObj.roll(2),WasCalled)
Interactive verification passed.

Roll one die. Then verify that the roll method was called at least twice with any inputs.

val = mock.roll(1);

testCase.verifyThat(withAnyInputs(behaviorObj.roll), ...
    WasCalled('WithCount',2))
Interactive verification passed.

Verify that NumSides was not accessed.

import matlab.mock.constraints.WasAccessed
testCase.verifyThat(behaviorObj.NumSides,~WasAccessed)
Interactive verification passed.

Set the color of the dice. Then verify the property was set once.

mock.Color = "blue";

import matlab.mock.constraints.WasSet
testCase.verifyThat(behaviorObj.Color,WasSet('WithCount',1))
Interactive verification passed.

Access the Color property. Then verify that it was not accessed exactly once. This test fails.

c = mock.Color

testCase.verifyThat(behaviorObj.Color,~WasAccessed('WithCount',1))
c = 

    "blue"

Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
Negated WasAccessed failed.
--> Property 'Color' was accessed the prohibited number of times.
    
    Actual property access count:
             1
    Prohibited property access count:
             1

Specified property access:
    PropertyGetBehavior
        <Mock>.Color

Set the number of sides. Then, verify that the number of sides was set to 22.

mock.NumSides = 22;
testCase.verifyThat(behaviorObj.NumSides,WasSet('ToValue',22))
Interactive verification passed.

Use a constraint from the matlab.unittest.constraints namespace to assert that the number of dice sides isn't set to more than 20. This test fails.

import matlab.unittest.constraints.IsLessThanOrEqualTo
testCase.verifyThat(behaviorObj.NumSides, ...
    WasSet('ToValue',IsLessThanOrEqualTo(20)))
Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
WasSet failed.
--> Property 'NumSides' was not set to the specified value.
--> Observed property set(s) to any value:
        <Mock>.NumSides = 22

Specified property set:
    PropertySetBehavior
        <Mock>.NumSides = <IsLessThanOrEqualTo constraint>

Summary of Qualifications

Type of QualificationTestCase Methodmatlab.mock.constraints Class
Use matlab.unittest.TestCase MethodWith matlab.mock.constraints Class
Method was calledverifyCalled or verifyNotCalledverifyThatWasCalled or Occurred
assumeCalled or assumeNotCalledassumeThat
assertCalled or assertNotCalledassertThat
fatalAssertCalled or fatalAssertNotCalledfatalAssertThat
Method was called a certain number of timesNot applicableverifyThat, assumeThat, assertThat, or fatalAssertThatWasCalled
Property was accessedverifyAccessed or verifyNotAccessedverifyThatWasAccessed or Occurred
assumeAccessed or assumeNotAccessedassumeThat
assertAccessed or assertNotAccessedassertThat
fatalAssertAccessed or fatalAssertNotAccessedfatalAssertThat
Property was accessed a certain number of timesNot applicableverifyThat, assumeThat, assertThat, or fatalAssertThatWasAccessed
Property was setverifySet or verifyNotSetverifyThatWasSet or Occurred
assumeSet or assumeNotSetassumeThat
assertSet or assertNotSetassertThat
fatalAssertSet or fatalAssertNotSetfatalAssertThat
Property was set a certain number of timesNot applicableverifyThat, assumeThat, assertThat, or fatalAssertThatWasSet
Property was set to a certain valueNot applicableverifyThat, assumeThat, assertThat, or fatalAssertThatWasSet or Occurred
Methods were called and properties were accessed or set in a particular orderNot applicableverifyThat, assumeThat, assertThat, or fatalAssertThatOccurred

See Also

Classes

Related Topics