NSubstitute - Используйте спецификации для всех аргументов одного типа. Проблема в TeamCity

У меня есть модульный тест с 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();
    }

Ошибка TeamCity:

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

Что может быть?


person Nerf    schedule 23.03.2017    source источник
comment
Вот некоторая информация по диагностике общей проблемы. Возможно, на TC тесты выполняются в другом порядке, и это вскрывает проблему?   -  person David Tchepak    schedule 24.03.2017


Ответы (1)


Обычно эта проблема возникает из-за спецификаций аргументов, которые не используются полностью (например, вы передаете Arg.Any<T>() не виртуальному методу). Есть много потенциальных сценариев, как это могло произойти. Причина, по которой вы видите, что в определенной среде может быть комбинация поврежденных тестов и параллелизма (мусор из одного теста используется в другом тесте, который, по-видимому, выполняется в том же потоке). Основная проблема здесь в том, что может быть действительно сложно устранить проблему, если у вас много тестов, поскольку каждый из них потенциально может привести к утечке спецификации аргумента.

Недавно я создал диагностический пакет, чтобы помочь устранить эту проблему. Это позволяет вам найти "просочившиеся" спецификации аргументов. Обратите внимание, это может значительно замедлить выполнение тестов, поэтому его следует отключить позже.

Шаги следующие:

  1. Скопируйте файл DiagnosticsSubstitutionContext.cs в свой проект с тестами.
  2. Измените соответствующее место путем записи в журнал или повторного создания пользовательского исключение с информацией обо всех поставленных в очередь спецификациях. В следующий раз, когда будет сгенерировано AmbiguousArgumentsException исключение, эта ловушка должна поймать виновника - спецификацию (и), оставшуюся после предыдущего выполнения теста. Значения полей Spec и CreationStack должны помочь вам найти точное место.
  3. Настройте свой код для запуска статического конструктора класса DiagnosticsSubstitutionContext перед выполнением тестов. Например, вы можете создать статический конструктор внутри класса атрибутов AutoNSubstituteData со следующим содержимым:

    DiagnosticsSubstitutionContext.Init()
    

После того, как исключение будет сгенерировано в следующий раз, у вас должна быть информация о нарушенной спецификации, поэтому вы найдете точное место.

P.S. Если вы сохраняете файлы .pdb во время выполнения тестов вы должны увидеть точную строку кода, в которой неработающая спецификация была поставлена ​​в очередь, в дополнение к имени метода.

person Alex Povar    schedule 12.04.2017