Не удалось зарегистрировать экземпляр в AutoFac? - PullRequest
0 голосов
/ 22 июня 2019

Я хочу использовать существующий макет моего проекта в AutoFac. Я не хочу переписывать мой код PROD. Итак, я нашел что-то AutoFac, которое не работает. Я думаю, что что-то упустил.

Я попробовал приведенный ниже код.

public AboutTideEditorMockTest () {
    aboutTideService = new AboutTideEditorService (iAboutTideEditorRepository.Object, exceptionLogServiceMock.Object);
    aboutTideServiceWithNullParam = new AboutTideEditorService (null, exceptionLogServiceMock.Object);
}

//This is my test case
[FactWithAutomaticDisplayName]
public void Test1 () {
    var cb = new ContainerBuilder ();
    var studyLoaderMock = new Mock<IAboutTideEditorService> ().Object;
    var studyLoaderMock1 = iAboutTideEditorRepository.Object;
    var studyLoaderMock2 = exceptionLogServiceMock.Object;
    cb.RegisterInstance (studyLoaderMock).As<IAboutTideEditorService> ();
    cb.RegisterInstance (studyLoaderMock1).As<IAboutTideEditorRepository> ();
    cb.RegisterInstance (studyLoaderMock2).As<IExceptionLogService> ();
    var container = cb.Build ();
    using (var scope = container.BeginLifetimeScope ()) {
        var component = scope.Resolve<AboutTideEditorService> ();
        responseData = component.AddAboutTideContent (applicationUser, aboutTide);
        Assert.Equal (ProcessStatusEnum.Invalid, responseData.Status);
    }
}

Я хочу использовать существующий макет, который я передаю в «RegisterInstance». Когда я пытаюсь отладить свой тестовый пример, я получаю "responseData" null. Я не могу зайти внутрь в AddAboutTideContent.

1 Ответ

0 голосов
/ 24 июня 2019

Вы не устанавливаете возвращаемое значение макета, и вам нужно разрешить IAboutTideEditorService вместо AboutTideEditorService.

Вам также нужно генерировать макеты по-другому.Однако нет необходимости изменять производственный код!

Сделайте это так:

[FactWithAutomaticDisplayName]
public void Test1() {
  var cb = new ContainerBuilder();

  var studyLoaderMock = new Mock<IAboutTideEditorService>();
  var studyLoaderMock1 = new Mock<IAboutTideEditorRepository>(); // you don't need that when resolving only IAboutTideEditorService
  var studyLoaderMock2 = new Mock<IExceptionLogService>(); // you don't need that when resolving only IAboutTideEditorService

  cb.RegisterInstance(studyLoaderMock.Object).As<IAboutTideEditorService>();
  cb.RegisterInstance(studyLoaderMock1.Object).As<IAboutTideEditorRepository>(); // you don't need that when resolving only IAboutTideEditorService
  cb.RegisterInstance(studyLoaderMock2.Object).As<IExceptionLogService>(); // you don't need that when resolving only IAboutTideEditorService

  var container = cb.Build();

  studyLoaderMock
    .Setup(x => x.AddAboutTideContent(It.IsAny<YourTypeHereForParameterA>,
                                      It.IsAny<YourTypeHereForParameterB>)
             .Returns(new MyResponseDataType()); // add the right types here necessary, I can't tell which types they are because I am not seeing the functions code

  using (var scope = container.BeginLifetimeScope()) {
    var component = scope.Resolve<IAboutTideEditorService>(); // changed to IAboutTideEditorService
    responseData = component.AddAboutTideContent(applicationUser, aboutTide);
    Assert.Equal(ProcessStatusEnum.Invalid, responseData.Status);
  }
}

Ваш вызов функции возвращал null, потому что это поведение по умолчанию для макета с Moq = MockBehavior.Loose.Если вы хотите, чтобы функция макета возвращала определенное значение для неявных или явных параметров, вы должны вызвать Setup(delegate) и Returns(objectInstance) или Returns(Func<ObjectType>).

В общем, ваша тестовая установка не 'не имеет большого смысла.В основном вы регистрируете макеты только в Autofac-контейнере, что делает сам контейнер неуместным для ваших тестов.Использование IoC для тестов обычно требуется только в том случае, если вы непосредственно тестируете реализацию, а не макеты.Эти тесты называются Integration-Tests.

Было бы более логично:

[FactWithAutomaticDisplayName]
public void Test1() {
  var cb = new ContainerBuilder();

  var studyLoaderMock1 = new Mock<IAboutTideEditorRepository>();that when resolving only IAboutTideEditorService
  var studyLoaderMock2 = new Mock<IExceptionLogService>();
  var studyLoader = new AboutTideEditorService(studyLoaderMock1.Object, studyLoaderMock2.Object);

  cb.RegisterInstance(studyLoader).As<IAboutTideEditorService>();

  var container = cb.Build();

  // now setup the functions of studyLoaderMock1 and studyLoaderMock2 
  // required for your function `AddAboutTideContent` from `IAboutTideEditorService` to work.

  using (var scope = container.BeginLifetimeScope()) {
    var component = scope.Resolve<IAboutTideEditorService>(); // changed to IAboutTideEditorService
    responseData = component.AddAboutTideContent(applicationUser, aboutTide);
    Assert.Equal(ProcessStatusEnum.Invalid, responseData.Status);
  }
}

Имейте в виду, что здесь я предполагаю порядок параметров, требуемых для AboutTideEditorService.Для получения дополнительной информации о том, как настроить макеты с Moq, посмотрите здесь .

...