简体   繁体   English

NSubstitute 无法确定要使用的参数规范

[英]NSubstitute cannot determine argument specifications to use

I use NUnit and NSubstitute for unit testing.我使用 NUnit 和 NSubstitute 进行单元测试。 I have the following:我有以下几点:

public interface IDataProvider
{
    void Log(int tvmId, DateTime time, int source, int level, int eventCode, string message);
}

...

var fakeDataProvider = Substitute.For<IDataProvider>();
...
fakeDataProvider.Received().Log(
    Arg.Any<int>(),
    new DateTime(2000, 1, 1),
    0,
    0,
    0,
    null);

fakeDataProvider.Received() throws AmbiguousArgumentException with the message that it cannot determine argument specifications to use. fakeDataProvider.Received() 抛出 AmbiguousArgumentException 并带有无法确定要使用的参数规范的消息。 I have found the following on SO我在 SO 上找到了以下内容

Cannot determine argument specifications to use 无法确定要使用的参数规范

which is related but I cannot apply it in the code above.这是相关的,但我不能在上面的代码中应用它。 Why is the above code ambiguous?为什么上面的代码有歧义? How else could I specify to Received() that it should accept any argument?我还能如何向 Received() 指定它应该接受任何参数?

Since you have several int parameters in the Log method, you have to use the argument specification for each and every one of them.由于Log方法中有多个int参数,因此您必须对每个参数使用参数规范。

fakeDataProvider.Received().Log(
    Arg.Any<int>(),
    new DateTime(2000, 1, 1),
    Arg.Is(0),
    Arg.Is(0),
    Arg.Is(0),
    null);

Well, another trap for young players: if you have several calls to the same method in a single test, do not reuse argument specifiers across calls:好吧,年轻玩家的另一个陷阱:如果您在一次测试中多次调用同一方法,请不要在调用之间重用参数说明符:

I have a virtual method that takes two Dictionary<string, MyStruct>:我有一个需要两个 Dictionary<string, MyStruct> 的虚拟方法:

var checkArg1 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
var checkArg2 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
mySubtitue.Received(1).myMethod(checkArg1, checkArg2);

// do something that triggers another call to MyMethod 
// ...

// second check using the same argument specifiers
mySubtitue.Received(1).myMethod(checkArg1, checkArg2);

You still get the "Please use specifications for all arguments of the same type".您仍然会收到“请对所有相同类型的参数使用规范”。

Solution is to instantiate each time the arguments specifiers:解决方案是在每次参数说明符时实例化:

var checkArg1 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
var checkArg2 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
mySubtitue.Received(1).myMethod(checkArg1, checkArg2);

// do something that triggers another call to MyMethod 
// ...

// second check using new argument specifiers
checkArg1 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
checkArg2 = Arg.Is<Dictionary<string, MyStruct>>(dico => dico.Count == 0);
mySubtitue.Received(1).myMethod(checkArg1, checkArg2);

You can use below code to do it您可以使用下面的代码来做到这一点

fakeDataProvider.Received().Log(
    Arg.Any<int>(),
    new DateTime(2000, 1, 1),
    Arg.Is(0),
    Arg.Is(0),
    Arg.Is(0),
    null);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM