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 Qualification | TestCase Method | matlab.mock.constraints Class | |
---|---|---|---|
Use matlab.unittest.TestCase Method | With matlab.mock.constraints Class | ||
Method was called | verifyCalled or verifyNotCalled | verifyThat | WasCalled or Occurred |
assumeCalled or assumeNotCalled | assumeThat | ||
assertCalled or assertNotCalled | assertThat | ||
fatalAssertCalled or fatalAssertNotCalled | fatalAssertThat | ||
Method was called a certain number of times | Not applicable | verifyThat , assumeThat , assertThat , or fatalAssertThat | WasCalled |
Property was accessed | verifyAccessed or verifyNotAccessed | verifyThat | WasAccessed or Occurred |
assumeAccessed or assumeNotAccessed | assumeThat | ||
assertAccessed or assertNotAccessed | assertThat | ||
fatalAssertAccessed or fatalAssertNotAccessed | fatalAssertThat | ||
Property was accessed a certain number of times | Not applicable | verifyThat , assumeThat , assertThat , or fatalAssertThat | WasAccessed |
Property was set | verifySet or verifyNotSet | verifyThat | WasSet or Occurred |
assumeSet or assumeNotSet | assumeThat | ||
assertSet or assertNotSet | assertThat | ||
fatalAssertSet or fatalAssertNotSet | fatalAssertThat | ||
Property was set a certain number of times | Not applicable | verifyThat , assumeThat , assertThat , or fatalAssertThat | WasSet |
Property was set to a certain value | Not applicable | verifyThat , assumeThat , assertThat , or fatalAssertThat | WasSet or Occurred |
Methods were called and properties were accessed or set in a particular order | Not applicable | verifyThat , assumeThat , assertThat , or fatalAssertThat | Occurred |