【问题标题】:NSubstitute cannot determine argument specifications to use when "Run All Tests" of projectNSubstitute 无法确定项目“运行所有测试”时要使用的参数规范
【发布时间】:2018-11-02 20:50:51
【问题描述】:

我有一个测试方法:

public class MyTests
{
  [Fact]
  public void Test_Method()
  {
     // Arrange 
     var returns = Result.Ok(new List<string>() { "Test" }.AsEnumerable());  

     this.mockService.ServiceMethod(Arg.Any<Guid>()).Returns(returns); //returns Result<IEnumerable<string>>


     //Act
     var actResult = this.anotherService.Backup();

     //Assert
     Assert.True(actResult.Success);
  }
  ...

测试这个方法:

public class AnotherService
{

  internal Result Backup()
  {
    var ret = this.mockService.ServiceMethod().Value;

    ...

    return Result.Ok();
  }

当我仅为Test_Method() 运行该方法时,一切正常。当我尝试为整个 MyTests 类运行时,此引用方法出现以下错误:

NSubstitute.Exceptions.AmbiguousArgumentsException: '无法确定 要使用的参数规范。请使用所有规格 相同类型的参数。'

我相信这个问题与这种情况无关: How NOT to use argument matchers

NSubstitute.Analyzers:

有什么事吗?

【问题讨论】:

  • 你应该为模拟服务定义返回值this.mockService.ServiceMethod(Arg.Any&lt;Guid&gt;()).Returns(Result.With(Enumerable.Empty&lt;string&gt;()))
  • 感谢法比奥!但是我已经尝试过了……但我仍然有同样的错误。我更新了问题。

标签: mocking nsubstitute


【解决方案1】:

在 cmets 和问题更新后更新:

如果在对我的原始答案进行更改后仍然存在问题,则可能是夹具中的另一个测试导致了问题。我建议将NSubstitute.Analyzers 添加到项目中,这样可以在编译时使用 Roslyn 发现 NSubstitute 使用的潜在问题。 (我建议将这个添加到所有使用 NSubstitute 的项目中;它确实可以帮助避免很多潜在的问题!)

如果 NSubstitute.Analyzers 没有发现错误,那么不幸的是,我们只剩下一些手动步骤,如 this answer 中所述。


原答案:

参数匹配器需要与指定调用或断言接收到调用结合使用。

您发布的测试有两个地方可能导致此问题:

  • 正如@Fabio 在评论中提到的那样,mockService.ServiceMethod() 中使用了一个参数匹配器,而没有对应的.Returns
  • 参数匹配器用于真正调用anotherService.Backup()

尝试像这样修改测试:

  [Fact]
  public void Test_Method()
  {
     // Arrange       
     this.mockService.ServiceMethod(Arg.Any<Guid>()).Returns(...);
     //                               ^- Arg matcher   ^- so need Returns()

     //Act
     var actResult = this.anotherService.Backup(Guid.NewGuid());
     //         Do not use arg matchers for real calls -^

     //Assert
     Assert.True(actResult.Success);
  }

在您的夹具中可能还有其他原因导致此问题,但参数匹配器的这两种用法肯定不会有帮助!

这些问题在你提到的argument matcher documentation中有描述;如果文档在这些方面不清楚,请raise an issue 提出改进本节的任何建议。从其他角度获取有关文档的输入非常有用,因此您在这方面所做的任何贡献都将非常感激!

【讨论】:

  • 嗨@Igor,我已经更新了我的答案。让我知道你是怎么做的! :)
  • @Igor 很抱歉给您带来了麻烦。堆栈跟踪指向哪一行?我们可能最好将其移至github.com/nsubstitute/NSubstitute/issues,以便我们可以分享更多信息(我不确定这是否适用于此时的 SO 问答)。为了提供帮助,我想我需要更多关于夹具中其他测试的信息(当您运行单个夹具时会发生这种情况,对吗?)。如果您可以通过夹具中的两个或三个测试来重现它并发布所涉及的类/接口的精简版本,那么我认为我们很有可能发现问题。
  • @感谢您的帮助!那么让我们继续在github上吧! :)
  • 昨天我搜索了我的整个测试代码以试图找出问题所在,我能够理解发生了什么:) 还有更多使用Arg. 进行实际调用的方法。我把它们都设置好了,一切正常!感谢您的帮助!我只是想了解为什么有些测试更早起作用:( ...但是...
  • @Igor 很高兴你把它整理好了!根据测试顺序,可以清除一些 arg 匹配器。下一个 NSubstitute 版本 (4.0) 旨在通过更早地检测这些问题来改进这一点。有关正在发生的事情的技术说明,请尝试 weareadaptive.com/2014/09/30/why-nsubstitute 从“NSubstitute 权衡”标题开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 2013-10-12
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
相关资源
最近更新 更多