【问题标题】:NSubstitute - Please use specifications for all arguments of the same type. Issue on TeamCityNSubstitute - 请对相同类型的所有参数使用规范。关于 TeamCity 的问题
【发布时间】:2017-03-23 09:16:40
【问题描述】:

我对 AutoFixture、NSubstitute 和 xUnit 进行了单元测试。

它在 VS 中通过本地开发机器但在 TeamCity 上失败。

测试:

        [Theory, AutoNSubstituteData]
    public async void GetList_StatusError_ShouldReturnBadRequest(
        [Frozen] ICommentsService _commentsService,
        [Frozen] IMerchantsService _merchantsService,
        [Frozen] ICampaignsService _campaignsService)
    {
        // Arrange   

        var output = _fixture.Build<CommentsResult<CommentOutput>>()
            .Without(w => w.Entity)
            .With(x => x.Status, ServiceActionStatus.Error)
            .Create();

        _commentsService.List(Arg.Any<int>(), Arg.Any<string>()).Returns(output);

        var controller = new CommentController(_commentsService, _merchantsService, _campaignsService);
        controller.Request = new HttpRequestMessage();
        controller.Configuration = new HttpConfiguration();

        // Act
        IHttpActionResult actionResult = await controller.GetList(null);
        var contentResult = actionResult as BadRequestErrorMessageResult;

        // Assert
        contentResult.Should().NotBeNull();
        contentResult.Message.Should().NotBeNullOrEmpty();
    }

团队城市错误:

    NSubstitute.Exceptions.AmbiguousArgumentsException: 
    Cannot determine argument specifications to use.
    Please use specifications for all arguments of the same type. at          NSubstitute.Core.Arguments.NonParamsArgumentSpecificationFactory.Create(Object argument, IParameterInfo parameterInfo, ISuppliedArgumentSpecifications suppliedArgumentSpecifications)

评论结果如下:

    public class CommentsResult<T> : IServiceResult<T>
    {
    public T Entity { get; set; }
    public string Message { get; set; }
    public Exception Exception { get; set; }
    public ServiceActionStatus Status { get; set; }
     }

什么是可以?

【问题讨论】:

标签: c# unit-testing autofixture


【解决方案1】:

通常会发生此问题,因为参数规范未完全使用(例如,您将 Arg.Any&lt;T&gt;() 传递给非虚拟方法)。有很多潜在的情况是如何发生的。您在特定环境中看到这种情况的原因可能是损坏的测试和并发性的组合(一个测试的垃圾被另一个似乎在同一线程上运行的测试消耗)。这里的主要问题是,如果您有大量测试,可能很难解决问题,因为每个测试都可能泄漏参数规范。

最近我创建了一个诊断套件来帮助解决此问题。它允许您找到“泄露”的参数规范。请注意,它可能会显着减慢测试的执行速度,因此应在之后禁用。

步骤如下:

  1. DiagnosticsSubstitutionContext.cs 文件复制到您的带有测试的项目中。
  2. 修改appropriate place,方法是记录或重新抛出自定义异常以及有关所有排队规范的信息。下次抛出AmbiguousArgumentsException 异常时,这个陷阱应该会抓住一个罪魁祸首——规范,它是上一次测试执行的遗留物。 SpecCreationStack 字段值应该可以帮助您找到确切的位置。
  3. 调整您的代码以在测试执行之前触发DiagnosticsSubstitutionContext 类的静态构造函数。例如,您可以在 AutoNSubstituteData 属性类中创建一个静态构造函数,其内容如下:

    DiagnosticsSubstitutionContext.Init()
    

下次抛出异常后,你应该有关于被破坏的规范的信息,所以你会找到一个准确的地方。

附:如果您在测试执行期间保留.pdb 文件,则除了方法名称之外,您应该能够看到破坏规范被排队的确切代码行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2011-05-14
    • 1970-01-01
    相关资源
    最近更新 更多