Использование autofac с moq

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

как я могу это сделать?

Я пробовал:

var AppContainer = ApplicationContainer.GetApplicationContainer();  
var cb = new ContainerBuilder();
cb.RegisterType<Mock<IStudyLoader>>().As<IStudyLoader>().SingleInstance();
cb.Update(AppContainer);

Я не хочу менять свой код, чтобы решить что-то другое, чем IStudyLoader, а Mock<IStudyLoader> нельзя заменить на IStudyLoader; электронная.г Mock<IStudyLoader>.Object - это взаимозаменяемый для IStudyLoader, но я не могу зарегистрироваться Mock<IStudyLoader>.Object потому что это не тип.

поправьте меня, пожалуйста, у меня такое ощущение, что мне не хватает что-то.

(у меня есть другое ограничение, я не могу использовать другой контейнер, чем ApplicationContainer.GetApplicationContainer())

(Я думаю, что лучше вручную вводить зависимость при тестировании, но я не хочу, чтобы изменить код на этот раз.)

5 ответов


Я нашел решение, Да, это возможно!

  var AppContainer = ApplicationContainer.GetApplicationContainer();
  var studyLoaderMock = new Mock<IStudyLoader>().Object;
  cb.RegisterInstance(studyLoaderMock).As<IStudyLoader>();
  cb.Update(AppContainer);

метод, который вы ищете, называется RegisterInstance:

var mock = ...;
var cb = new ContainerBuilder();
cb.RegisterInstance(mock.Object);
var container = cb.Build();

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

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


У меня нет особого опыта работы с autofac, но большинство других контейнеров, с которыми я работал, позволяют зарегистрировать экземпляр объекта, который уже создан. Таким образом, вы можете создать свой макет, а затем зарегистрировать макет.Объект как реализация для IStudyLoader. Обратитесь к документации autofac о том, как это сделать.


поскольку этот вопрос был задан, есть теперь AutoFac.Extras.Moq пакет, поддерживаемый AutoFac:

http://autofaccn.readthedocs.io/en/latest/integration/moq.html

Это позволяет создавать на ходу зависимости в рамках модульных тестов.


старый вопрос, но AutoFac теперь с версии 4.0.1 поддержка один moq4 и обеспечить дополнительный пакет, который вы можете установить Autofac.Дополнительный.Обьем Moq

    Install-Package Autofac.Extras.Moq

Autofac.Дополнительный.Moq авто установить AutoFac и Moq

вам не нужно создавать контейнер и регистрировать StudyLoader. Он неявно определяется Autofac.Дополнительный.Обьем Moq.

Autofac.Дополнительный.Moq ценен для вложенных зависимостей. Вы не хотите регистрировать весь график зависимостей. Только издевайтесь над объектом SystemUnderTest SUT

вы можете реализовать тестовый случай, как показано ниже:

         [TestFixture]
        class StudyLoaderTest
        {
            [Test]
            public void Test()
            {
                using (var mock = AutoMock.GetLoose())
                {
                    // The AutoMock class will inject a mock IStudyLoader
                    // into the StudyLoader constructor
                    //no need to create/configure a container
                    var studyLoader = mock.Create<StudyLoader>();               
                    Assert.AreEqual("hi AutoFac Moq", studyLoader.Name);
                }
            }
        }

         class StudyLoader : IStudyLoader
        {
            public string Name { get; set; } = "hi AutoFac Moq";
        }
         interface IStudyLoader
        {
            string Name { get; set; }
        }