如何在每次调用模拟方法时返回不同的输出

时间:2017-09-18 15:55:21

标签: matlab unit-testing mocking

我在MATLAB Answers上交叉发布此question I asked

我正在尝试使用新的MATLAB模拟框架来测试计算图像帧流的运行方差的类方法。方法的输入通常来自另一个数据类。我想做的是让一个模拟器在每次调用时返回一个正态分布的随机帧,然后进行一个测试,检查在一些大量的帧后,返回的方差是否为1(在一个公差)。

如果我这样写我的方法:

    function mock = makeMock(obj)
        [mock, b] = createMock(obj, 'AddedMethods', {'r'});
        import matlab.mock.actions.AssignOutputs;
        rng(1)
        x = @() randn(obj.rows, obj.cols);
        when(withAnyInputs(b.r), repeat(32, AssignOutputs(x())));
    end

然后在分配输出时,评估randn并且输出是静态的,所以我的所有帧都是相同的。我尝试的第二件事是一次添加多个帧作为列表:

    function mock = makeMock(obj)
        [mock, b] = createMock(obj, 'AddedMethods', {'r'});
        import matlab.mock.actions.AssignOutputs;
        rng(1)
        x = num2cell(randn(obj.rows, obj.cols, 32), [1 2]);
        when(withAnyInputs(b.r), AssignOutputs(x{:}));
    end

这仍然只给出了第一帧,因为AssignOutputs deal是输出变量的值,所以我总是只请求第一帧。

我尝试的最后一件丑事是:

        when(withAnyInputs(b.r), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            then(AssignOutputs(randn(obj.rows, obj.cols)), ...
            AssignOutputs(randn(obj.rows, obj.cols))) ...
            )))))))))))))))))))))))))))))));

这给了我一个错误,说我的嵌套太深了。

我会注意到我正在尝试测试的方法需要将整个模拟对象作为输入,而不仅仅是框架,因此只能传递一个随机帧。它是一个更大,更大的代码库的一部分,所以简单地重写被测试的方法直接获取框架目前是不可能的,如果没有显着重构许多其他的,所以我现在坚持以这种方式进行测试。

有一种优雅的方式来做我想做的事吗?

1 个答案:

答案 0 :(得分:2)

我在MATLAB答案上发了一个答案: https://www.mathworks.com/matlabcentral/answers/357200-how-can-i-make-a-mock-method-return-different-answers#answer_282110

总结:

  • 没有干净的方法来做这件事
  • 但是,可以在循环中构建操作列表
import matlab.mock.actions.AssignOutputs;
[mock, b] = createMock(obj, 'AddedMethods', {'r'});
rng(1)
n = 32;
action = AssignOutputs(randn(obj.rows, obj.cols));
for i = 1:n-1
    action = action.then(AssignOutputs(randn(obj.rows, obj.cols)));
end
when(withAnyInputs(b.r), action);