A .NET Unit Test without a parameterless constructor, to facilitate dependency injection

前端 未结 2 1314
逝去的感伤
逝去的感伤 2021-02-19 22:00

I\'m trying to have the unit tests not rely on calling container.Resolve() for their dependencies.

I\'m currently using AutoFac 2.2.4,

2条回答
  •  执笔经年
    2021-02-19 22:18

    I just allow my tests to have a dependency on Autofac, although I encapsulate it. All of my TestFixtures inherit from Fixture, which is defined as such:

    public class Fixture
    {
        private static readonly IContainer MainContainer = Ioc.Build();
        private readonly TestLifetime _testLifetime = new TestLifetime(MainContainer);
    
        [SetUp]
        public void SetUp()
        {
            _testLifetime.SetUp();
        }
    
        [TearDown]
        public void TearDown()
        {
            _testLifetime.TearDown();
        }
    
        protected TService Resolve()
        {
            return _testLifetime.Resolve();
        }
    
        protected void Override(Action configurationAction)
        {
            _testLifetime.Override(configurationAction);
        }
    }
    
    public class TestLifetime
    {
        private readonly IContainer _mainContainer;
    
        private bool _canOverride;
        private ILifetimeScope _testScope;
    
        public TestLifetime(IContainer mainContainer)
        {
            _mainContainer = mainContainer;
        }
    
        public void SetUp()
        {
            _testScope = _mainContainer.BeginLifetimeScope();
            _canOverride = true;
        }
    
        public void TearDown()
        {
            _testScope.Dispose();
            _testScope = null;
        }
    
        public TService Resolve()
        {
            _canOverride = false;
            return _testScope.Resolve();
        }
    
        public void Override(Action configurationAction)
        {
            _testScope.Dispose();
    
            if (!_canOverride)
                throw new InvalidOperationException("Override can only be called once per test and must be before any calls to Resolve.");
    
            _canOverride = false;
            _testScope = _mainContainer.BeginLifetimeScope(configurationAction);
        }
    }
    

提交回复
热议问题