How to change property behavior for a mocked object

16 ビュー (過去 30 日間)
TADA
TADA 2019 年 6 月 25 日
編集済み: men8th 2023 年 4 月 19 日
I'm trying to use the mocking framework for unit tests
I'm trying to make the property of a mock object return another mock object, but the behavior object doesn't have the property
classdef MyClass
properties (GetAccess=public, SetAccess=protected)
prop1;
end
methods
function this = answer()
end
end
end
this is the mock decleration:
testCase = matlab.mock.TestCase.forInteractiveUse;
[mock,behav] = testCase.createMock(?MyClass);
% this would obciously throw an exception because the property set method is protected
mock.prop1 = "";
You cannot set the read-only property 'prop1' of MyClassMock.
% this throws an exception because the behavior object doesn't have this property
p = behav.prop1;
No appropriate method, property, or field 'prop1' for class 'matlab.mock.classes.MyClassBehavior'.
now i can't set the value of the mock object because the set access is protected
and i can't use the behavior object to change the property behavior because I can't find the propertyBehavior thing anywhere
I'm obviously missing something, but all the examples I've seen in the documentation show how to use a custom mock object with "AddedProperties"
and I could be tackling this the wrong way, but I prefer to create the mock object using the meta class

採用された回答

M Wells
M Wells 2019 年 8 月 15 日
編集済み: M Wells 2019 年 8 月 15 日
Mock objects are still a recent feature of MATLAB and I don't think they are practical for testing classes yet. There are still quite a few features that are lacking for sufficiantly replicating object behaviour, for instance having a mock object method call assign a value to a protected property.
The solution to the above case is to create your mock without using the meta-class instance:
testCase = matlab.mock.TestCase.forInteractiveUse;
[MyClassMock, behaviour] = createMock(testCase, 'AddedProperties', "prop1", 'AddedMethods', "answer")
testCase.assignOutputsWhen(get(behaviour.prop1), 'abc')
p = MyClassMock.prop1
It's not ideal but I don't think there's any other option at this time. You can still test for access violations this way:
import matlab.mock.actions.ThrowException
when(set(behaviour.prop1),...
ThrowException(MException('MATLAB:class:SetProhibited',...
'You cannot set the read-only property ''prop1'' of MyClass.')))
Creating a mock from a meta-class only works for classes with abstract properties and methods.
  4 件のコメント
Wolf Blecher
Wolf Blecher 2023 年 1 月 10 日
編集済み: Wolf Blecher 2023 年 1 月 10 日
Now that the feature is not so recent any more, using
testCase.assignOutputsWhen(get(behaviour.propA),"Something")
still fails.
Any possibility that this gets the rank of a useful feature somewhen?
Having a class with more than one property and several methods, the aforementioned solution is not practicable.
men8th
men8th 2023 年 4 月 19 日
編集済み: men8th 2023 年 4 月 19 日
I've successfully used the technique suggested by TADA in the comment above to generate mock objects which override the .isa method. A few pointers:
  1. When overriding the .isa, you have to return a char vector, not a string. For example this works: testCase.assignOutputsWhen(mockBehaviour.isa('MyClass'),true), but this does not testCase.assignOutputsWhen(mockBehaviour.isa("MyClass"),true)
  2. A way around this cludge might be to move to a scheme where all classes are defined with an abstract interface which basically does nothing apart from define properties and methods. I'm no expert but have seen this with C# where all classes are set up with an interface IMyClass and a concrete version MyClass. Not sure how well this would work in practice, and it seems a lot of work.
I agree with Wolf Blecher - please can we have some more development work on this Mathworks.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMock Dependencies in Tests についてさらに検索

製品


リリース

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by