c# - 单元测试。为什么 Mock 在第二次循环迭代中返回不同的值?

标签 c# unit-testing mocking moq

我在以下对象上有一个 Mock,其工作是收集传感器数据。它实现了这个接口(interface):

public interface ISensorDataCollector
{
    List<int> CollectSensorData(int amountOfValues);        
}

在测试中我有以下安排:

// ARRANGE
var collector = new Mock<ISensorDataCollector>() { CallBase = true };
// Mock SensorDataCollector
collector.Setup((x) => x.CollectSensorData(10)
         .Returns(new List<int> { 1,2,3,4,5,6,7,8,9});
myProcess.AdwSensorDataCollector = collector.Object;

// ACT
myProcess.CollectSensorDataRepeatIfFails(5);

要测试的方法有一个 while 循环,在该循环中收集数据。简单版本如下所示:

public ISensorDataCollector SensorDataCollector { get; set; }

public void CollectSensorDataRepeatIfFails(int counterForRepeatedMeasurement)
{        
    do
    {
        List<int> values = this.SensorDataCollector.CollectSensorData(10); 

        values.Clear();

        counterForRepeatedMeasurement--;
    } while (counterForRepeatedMeasurement >= 0);
}

问题:从 this.AdwSensorDataCollector.CollectSensorData(10); 行的第二次迭代开始返回一个空列表。但我希望它每次都能返回我在设置中指定的值:

collector.Setup((x) => x.CollectSensorData(10)
         .Returns(new List<int> { 1,2,3,4,5,6,7,8,9});

我猜它与 values.Clear(); 有关,因为如果我删除列表清除。 CollectSensorDataRepeatIfFails 的返回值在所有迭代中保持不变,我的问题就消失了。但这只是一个猜测。我很想知道为什么第二次调用没有返回指定的返回值。

问题:我错过了什么?该设置是否仅适用于模拟方法的 1 次调用?或者是否有一个按钮我忘记按下以使其按预期方式运行?为什么清空列表会影响第二次调用mocked方法的返回值?有人可以阐明这个问题吗?

我在询问之前做了一些研究,但我只能找到解释如何使模拟在下次调用时返回不同值的帖子。但是没有使用循环出现问题的帖子。我也很高兴重复提示。

干杯

最佳答案

What did I miss? Does the setup work only for 1 invocation of the mocked method?

实际上这是模拟的预期行为。该设置是可变的,因为您可以更改捕获的参数或通过引用返回值。您正通过 values.Clear(); 做到这一点。为避免此问题,只需通过提供工厂来推迟列表的创建。像这样:

collector.Setup((x) => x.CollectSensorData(10))
    .Returns<int>((i) => new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 });

关于c# - 单元测试。为什么 Mock 在第二次循环迭代中返回不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55019060/

相关文章:

asp.net-core - 如何通过最小起订量验证扩展方法

c# - 我如何断言/验证受最小起订量保护的方法?

c# - 关键字 'event' 在 C# 中是可选的吗?

c# - GridView 人口

c# - 如何使用正确的参数测试方法的调用?

android - 按照 Android Studio 的建议删除多余的转义会导致应用程序崩溃

python - 为不同的响应模拟 urllib2.urlopen().read()

C# 4.0 - 间隔上的线程

c# - 如何在 Xamarin.Mac 中执行终端命令并读入其输出

python - 使用unittest和mock修补python函数中的变量