Использование макета, созданного AutoFixture, в конкретной реализации

У меня есть следующая проблема с AutoFixture, описанная в коде

public SUT(IConcrete concrete)
{
    DTO BuildDTO()
    {
         return new DTO 
         {
             URL = concrete.GetString(arg1, arg2);
         };
    }
}

public Concrete : IConcrete
{
    public Concrete(ISomeHandler someHandler)
    {
        ...
    }

    public GetString(obj arg1, obj arg2)
    {
        return someHandler.GetUri(arg1, arg2);
    }
}

public void Test(
[Frozen] Mock<ISomeHandler> someHandler,
SUT mySUT)
{
    someHandler.Setup(...);
    mySUT.DoStuff();
    //assert everything went as expected
}

Моя проблема просто в том, как мне зарегистрировать IConcrete с помощью AutoFixture таким образом, чтобы я мог получить доступ к замороженному макету, который должен быть введен в него в тестовом примере?

На самом деле речь идет о внедрении HttpRequestMessage в преобразователь URL-адресов, который используется в обработчике, вызываемом из контроллера в проекте веб-API.

Я попытался зарегистрировать IConcrete с помощью созданного макета autofixture.

fixture.Register<IConcrete>(new Mock<ISomeHandler>());

но тогда я не могу получить доступ к этому макету в модульном тесте и настроить возвращаемое значение.

Заранее спасибо за любую помощь :)


person Jesper Bangsholt    schedule 14.07.2016    source источник
comment
Если SUT зависит от IConcrete, то зачем вообще заботиться о ISomeHandler?   -  person Mark Seemann    schedule 14.07.2016
comment
Я забочусь об ISomeHandler, потому что он выводит URL-адрес, и я хотел бы убедиться, что он сгенерирован правильно.   -  person Jesper Bangsholt    schedule 15.07.2016
comment
В предоставленном коде нет взаимодействия между SUT и ISomeHandler.   -  person Mark Seemann    schedule 15.07.2016
comment
Я добавил дополнительный код, чтобы показать взаимодействие между SUT и ISomeHandler.   -  person Jesper Bangsholt    schedule 15.07.2016
comment
Таким образом, проблема сводится к следующему: Как заставить AutoFixture зарегистрировать IConcrete с помощью фиктивного ISomeHandler.   -  person Jesper Bangsholt    schedule 15.07.2016
comment
SUT по-прежнему не взаимодействует с ISomeHandler. Он вызывает IConcrete.GetString. Вам нужно только предоставить тестового двойника для IConcrete.   -  person Mark Seemann    schedule 15.07.2016
comment
Спасибо, Марк, я понял, что мне нужно протестировать IConcrete самостоятельно, а затем, в этом случае с SUT, я могу использовать URL-адреса, сгенерированные автоматической фиксацией, поскольку я знаю, что IConcrete сам по себе будет генерировать правильные URL-адреса.   -  person Jesper Bangsholt    schedule 15.07.2016


Ответы (1)


Чтобы разрешить AutoFixture создавать макеты, необходимо включить контейнер AutoMocking.

Вам необходимо сделать следующее:

  1. Создайте AutoMoqAttribute:

    public class AutoMoqDataAttribute : AutoDataAttribute
    {
      public AutoMoqDataAttribute()
        : base(new Fixture().Customize(new AutoMoqCustomization()))
      {
      }
    }
    
  2. Украсьте свой тест новым атрибутом:

    [Theory, AutoMoqData]
    public void Test(
      [Frozen] Mock<ISomeHandler> someHandler,
      Sut sut)
    {
      someHandler.Setup(s => s.DoStuff()).Returns("123");
      Assert.Equal("123", sut.SomeHandler.DoStuff());
    }
    

Где Sut и ISomeHandler следующие:

public class Sut
{
  public Sut(ISomeHandler someHandler)
  {
    SomeHandler = someHandler;
  }

  public ISomeHandler SomeHandler { get; }
}

public interface ISomeHandler
{
  string DoStuff();
}
person Serhii Shushliapin    schedule 14.07.2016