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

NSubstitute cannot determine argument specifications to use

我使用 NUnit 和 NSubstitute 进行单元测试。我有以下内容:

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() 抛出 AmbiguousArgumentException 并显示无法确定要使用的参数规范的消息。我在 SO

上找到了以下内容

Cannot determine argument specifications to use

这是相关的,但我不能在上面的代码中应用它。为什么上面的代码有歧义?我还能如何指定 Received() 它应该接受任何参数?

由于在 Log 方法中有多个 int 参数,因此必须为每个参数指定参数。

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

好吧,年轻玩家的另一个陷阱:如果您在一次测试中多次调用同一个方法,请不要在调用之间重复使用参数说明符:

我有一个虚方法需要两个 Dictionary:

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);

您仍然收到“请对所有相同类型的参数使用规范”。

解决方法是每次实例化参数说明符:

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);

您可以使用下面的代码来完成

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