Макет Autofac.IComponentContext с модульными тестами C#

Я пытаюсь издеваться IComponentContext с NSubstitute, как показано ниже:

[TestClass()]
public class SyncRepositoryFactoryTests
{
    private IComponentContext _container;
    private SyncRepositoryFactory _factory;

    [TestInitialize]
    public void Initialize()
    {
        _container = Substitute.For<IComponentContext>();
        _factory = new SyncRepositoryFactory(_container);
    }

    [TestMethod]
    public void Get_SyncRepositoryOfITestEntity_Success()
    {
        var repository = Substitute.For<IRepository<TestEntity>>();
        _container.Resolve<IRepository<TestEntity>>().Returns(repository);

        var result = _factory.Get<ITestEntity>();

        Assert.IsNotNull(result);
        Assert.IsTrue(result is ISyncRepository<ITestEntity>);
    }

    public interface ITestEntity 
    {
    }

    public class TestEntity : ITestEntity
    {
    }
}

но я получаю исключение:

 ComponentNotRegisteredException: запрошенный сервис 
        "Hvb.eMarketAdvisor.Repository.SharePoint.IRepository`1[[Hvb.eMarketAdvisor.
        Repository.SharePoint.Tests.Units.SyncRepositoryFactoryTests+TestEntity, 
        Hvb.eMarketAdvisor.Repository.SharePoint.Tests.Units, 
    Версия =1.0.0.0, Культура = нейтральная, PublicKeyToken=null]]'не была зарегистрирована. 

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

Как я пытаюсь создать макет почему IComponentContext попытаться разрешить зависимость?

1 ответ

Так как Resolve<>() является методом расширения, и поэтому вы просто выполняете метод расширения, а не насмехаетесь над его вызовом. Вам нужно смоделировать вызов, который вызывает метод расширения.

Как сказали выше комментаторы, если вы издеваетесь над своим DI-контейнером, что-то не так с вашим дизайном.

Старый вопрос, но если кто-то придет сюда, чтобы узнать, как это сделать по какой-либо причине, с Autofac 4.9.2 для вас должно работать следующее. Очевидно, что если вам нужно больше логики, вы можете поэкспериментировать с заменами.

public interface ICalculate
{
    bool ProcessData();
}

public class ReallyCoolCalculate : ICalculate
{
    public bool ProcessData()
    {
        return 2 + (2 * 3) == 8;
    }
}

public void GetCalculateFromAutoFac()
{
    var calculate = new ReallyCoolCalculate();

    var componentContext = Substitute.For<IComponentContext>();
    var componentRegistration = Substitute.For<IComponentRegistration>();
    componentContext.ComponentRegistry.TryGetRegistration(Arg.Any<Service>(), out Arg.Any<IComponentRegistration>()).Returns(true);
    componentContext.ResolveComponent(Arg.Any<IComponentRegistration>(), Arg.Any<IEnumerable<Parameter>>()).Returns(calculate);

    var calculateFromAutoFac = componentContext.Resolve<ICalculate>();

}

Другие вопросы по тегам