NSubstitute 错误 UnexpectedArgumentMatcherException

问题描述 投票:0回答:5

我收到以下错误:

NSubstitute.Exceptions.UnexpectedArgumentMatcherException:'参数 匹配器(Arg.Is、Arg.Any)只能用于代替成员 论据。请勿在 Returns() 语句或其他任何地方使用 在会员通话之外。正确使用:
sub.MyMethod(Arg.Any()).Returns("hi") 错误使用:
sub.MyMethod("hi").Returns(Arg.Any())'

当尝试模拟以下界面时:

public interface IMyDate
{
    DateTime GetDate();
}

这是我嘲笑它的地方:

var myDate = Substitute.For<IMyDate>();
myDate.GetDate().Returns(testDate); // Error thrown here

请谁能解释一下我做错了什么?

var myDate = Substitute.For<IMyDate>();
myDate.GetDate().Returns(new DateTime(2018, 04, 05)); // Error thrown here

给出相同的结果。

c# mocking nsubstitute
5个回答
6
投票

这可能是由于早期测试的问题造成的。请参阅此答案了解追踪此问题的一些步骤。我在下面附上了该答案的快照:

这很可能是由于之前使用参数匹配器进行的测试所致 针对非虚拟方法,或在 Returns 语句中。

不幸的是,调试起来非常棘手。第一步是看 如果您在该装置中运行所有测试时出现问题。如果 因此,检查该装置中 Arg.Is|Any 的所有使用,从 一个在测试失败之前立即运行的测试(如果您的测试 框架使用可预测的测试顺序,否则您需要查看 在测试日志中查看失败的测试进行了哪些测试)。

如果该灯具没有出现这种情况,您需要查看 预先运行以查看剩余的 arg 匹配器在哪里的装置 来自(哪里。它很可能接近失败的测试。

希望这有帮助。好消息是,下一个 NSubstitute 版本 (v4) 将在这些情况下提供更多帮助。

另请参阅:如何不使用参数匹配器


5
投票

在我们的例子中,随机测试发送此错误消息,但仅在运行所有测试时才发送。我们在从 4.6.1 迁移到 netcore 3.1 时发现了这个错误。

问题在于,没有任何替代品的测试类正在使用

Arg.Any<int>()
表达式,原因未知。

删除这段未预料到的代码

Arg.Any<int>()
就是解决方案。


2
投票

最有可能

testDate
是参数匹配器(
Arg.Is
Arg.Any

异常消息告诉您仅使用参数匹配器作为成员调用参数,而不是作为返回值,但您正在将其用作返回值...

“不要在 Returns() 语句或成员调用之外的任何其他地方使用”

尝试

var testDate = new DateTime(); //<-- try setting the desired date as needed
var myDate = Substitute.For<IMyDate>();
myDate.GetDate().Returns(testDate);

参考N替代:参数匹配器


0
投票

我遇到了问题。并且异常是在一个测试类(文件)中抛出的,但问题的原因是在不同的测试类(文件)中

问题是Arg.Any<>()

    [Test]
    public void CaptureAsync_Success()
    {
        Assert.Throws<NotImplementedException>(() => _sut.CaptureAsync(Arg.Any<string>));
    }

我使用 string

类型的实例解决了这个问题
    [Test]
    public void CaptureAsync_Success()
    {
        Assert.Throws<NotImplementedException>(() => _sut.CaptureAsync("test"));
    }

0
投票

我知道这是一个老问题,但得票最高的答案暗示了正确的方向。

解决此问题的最佳方法是准确找到 NSubstitute 被滥用的位置,为此,有一个excellent包 NSubstitute.Analyzers(适用于 C# 或 VB),它会在构建项目时向您发出警告。

对我来说真的很有帮助,它直接指出了问题所在。 就我而言,我替换的是一个类而不是它的接口,当然我无法在其上使用聪明的方法。更改它以替代界面并且效果非常好。

我希望这对其他人有用!只需阅读此软件包中的警告,您一定会找到出路。

© www.soinside.com 2019 - 2024. All rights reserved.