Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Moq返回设置在第二次执行时返回错误数据_C#_Unit Testing_Moq - Fatal编程技术网

C# Moq返回设置在第二次执行时返回错误数据

C# Moq返回设置在第二次执行时返回错误数据,c#,unit-testing,moq,C#,Unit Testing,Moq,我在设置单元测试中的返回值时遇到问题,导致在第二次执行时返回意外数据 我正在测试我创建的一个服务,我有下面的代码来设置来自服务中使用的接口的返回数据 _dataService.Setup(x => x.GetJsonFromApi(It.IsAny<string>(), API_KEY, ENTITY_A)) .Returns(Task.FromResult(new List<Entity>() {

我在设置单元测试中的返回值时遇到问题,导致在第二次执行时返回意外数据

我正在测试我创建的一个服务,我有下面的代码来设置来自服务中使用的接口的返回数据

         _dataService.Setup(x => x.GetJsonFromApi(It.IsAny<string>(), API_KEY, ENTITY_A))
            .Returns(Task.FromResult(new List<Entity>() {
                new Entity {
                    Forename = "first_name",
                    Surname = "last_name",
                    EntityType = ENTITY_A
                }
            }));
        _dataService.Setup(x => x.GetJsonFromApi(It.IsAny<string>(), API_KEY, ENTITY_B))
            .Returns(Task.FromResult(new List<Entity>() {
                    new Entity {
                        Forename = "first_name",
                        Surname = "last_name",
                        EntityType = ENTITY_B
                    }
            }));
        _dataService.Setup(x => x.GetJsonFromApi(It.IsAny<string>(), API_KEY, ENTITY_C))
            .Returns(Task.FromResult(new List<Entity>() {
                    new Entity {
                        Forename = "first_name",
                        Surname = "last_name",
                        EntityType = ENTITY_C
                    }
            }));
第二次执行时;第一个调用(例如,
\u apiDataService.GetJsonFromApi(apirl,apiKey,ENTITY_A))
返回的是三个对象的列表,而不是预期的对象。我允许调试器使用data.AddRange()继续执行以下两个调用,并且在第二次执行时从这两个调用返回预期的单个对象,并将其添加到列表中,因此我最终得到五个对象

有人能告诉我我做错了什么吗

其他一些信息:

该代码在单元测试方法中执行两次,如下所示:

    apiCheckerService.AddEntitiesHash(client.Id).GetAwaiter().GetResult();
    apiCheckerService.AddEntitiesHash(client.Id).GetAwaiter().GetResult();
传递给
GetJsonFromApi
方法的属性都是字符串,实体_A、实体_B和实体_C都是常量,因此在第二次执行时,传递给函数的所有参数应该完全相同。 我正在测试服务的另一部分,该部分应该在第二次运行时锁定,但需要正确运行才能进行测试。

很可能(像99%的情况下)这是因为您使用了一个重载
。Returns()
,它具有一个随时可用的值。请注意代码中
.Returns()
的参数是什么:这是一项任务。已经建造好了。由一个值构造而成。已构造的值。这是一份清单

这意味着mock将记住这个列表对象,并在以后重用它。只要有任何东西想使用给定的参数
GetJsonFromApi
,它们就会得到完全相同的对象实例。您的mock不会给他们一个包含类似内容的新列表(就像一个正常的HTTP/etc客户机的行为),但会始终返回相同的对象实例

现在,如果您的代码在其他地方获得该列表并向其添加新项,会发生什么情况?你的嘲笑不会引起注意。它仍然很乐意返回相同的列表实例。现在有更多的项目

我打赌这就是发生的事情

因此,
.Returns
方法还有一个重载,它接受委托:

而不是:
foo.Returns(新列表{1,2,3})

尝试使用:
foo.Returns(()=>newlist{1,2,3})

而不是:
foo.Returns(Task.FromResult(新列表{1,2,3}))

尝试使用:
foo.Returns(()=>Task.FromResult(新列表{1,2,3}))

甚至:
foo.ReturnsAsync(()=>newlist{1,2,3})

这样,mock缓存的唯一对象就是lambda,并且在调用mock方法之前不会执行lambda。然后,每次调用模拟方法时,都会再次执行lambda,并返回一个新构造的对象。若以后有任何代码修改该对象,那个么这无关紧要,因为下一次调用mock方法将构建另一个新的响应

    apiCheckerService.AddEntitiesHash(client.Id).GetAwaiter().GetResult();
    apiCheckerService.AddEntitiesHash(client.Id).GetAwaiter().GetResult();