我有一个单元测试,我使用 .Returns() 返回一些示例数据:
[TestMethod]
public void TestRetrieveElementsInVersion()
{
IRetrieveElementSequence component = Substitute.For<IRetrieveElementSequence>();
List<UnconstructedElement> list = new List<UnconstructedElement>
{
new UnconstructedElement{Version = "1"},
new UnconstructedElement{Version = "2"}
};
component.RetrieveElements().Returns(list); // exception reported here
const string target = "1";
IRetrieveElementSequence service = new RetrieveElementsInAVersion(component, target);
IList<UnconstructedElement> result = service.RetrieveElements();
bool check = result.All(e => e.Version == target);
Assert.IsTrue(check);
}
当测试单独运行时,此代码使用 ReSharper 运行程序在 Visual Studio 中传递。当它作为列表的一部分运行时,就像我从解决方案运行所有测试时一样,它会失败。
NSubstitute.Exceptions.UnexpectedArgumentMatcherException:参数匹配器(Arg.Is、Arg.Any)只能用于代替成员参数。请勿在 Returns() 语句或成员调用之外的任何其他地方使用。
我什至不知道我在哪里使用 Arg.Any 或 Arg.Is。我做了什么让 NSubstitute 抱怨的事情?当我使用 .Returns() 返回非本机对象列表时会发生这种情况。
这很可能是由于之前使用参数匹配器针对非虚拟方法进行的测试,或者在
Returns
语句中。
不幸的是,调试起来非常棘手。第一步是查看当您在此装置中运行所有测试时是否出现问题。如果是这样,请检查该固定装置中
Arg.Is|Any
的所有使用,从失败的测试之前立即运行的那个开始(如果您的测试框架使用可预测的测试顺序,否则您需要查看测试日志以了解什么)测试继续失败的测试)。
如果该固定装置没有发生这种情况,您将需要查看之前运行的固定装置,以查看剩余的 arg 匹配器来自何处。它很可能接近失败的测试。
编辑 2021-03-28:NSubstitute.Analyzers 包可以帮助在编译时发现这些问题。我强烈建议将其添加到任何包含 NSubstitute 的测试项目中。
就我而言,这是对扩展方法的 Received() 调用(可能是因为它不是虚拟的)。 所以我回到我的拉取请求并删除了它的每个实例,它起作用了。