MATLAB Answers

0

How to change property behavior for a mocked object

TADA 님이 질문을 제출함. 25 Jun 2019
최근 활동 TADA 님이 댓글을 추가함. 19 Aug 2019
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

  댓글 수: 0

로그인 to comment.

제품


릴리스

R2018b

답변 수: 1

M Wells 님의 답변 15 Aug 2019
M Wells 님이 편집함. 15 Aug 2019
 채택된 답변

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.

  댓글 수: 2

Thank you for your answer.
I can use that approach, but then the mock object will not be a derived class of MyClass
That is fine if I use duck typing, but I will need to change quite a bit of my code for that, because I use property type validation in many cases (interfaces and such).
Or I can try to fool matlab into thinking the mock is derived from MyClass by overriding methods like class, isa, metaclass etc. I'm not sure this will work and either way it seems that even if it does work it will break as soon as I install the next Matlab version
So it seems my options are these:
  1. remove type validation systemwise and go back to duck typing
  2. create and maintain my own mocked objects
  3. write suit tests instead of unit tests
So apparently, it is enough to override isa for matlab to pass property type validations
[mock, mb] = createMock(testCase, 'AddedProperties', "prop1", 'AddedMethods', ["answer", "isa"])
testCase.assignOutputsWhen(mb.isa('MyClass'),true)
So I might do that after all

로그인 to comment.



Translated by