1

我的情況很常見,但我找不到答案。 我有集成測試,在每個設置一些服務被嘲笑。我必須更新Autuofac容器才能獲得這些mock的構造器注入。所以基本上我有主容器與所有應用程序註冊,並且需要爲每個測試場景的這些重寫服務創建一些子容器/生命週期範圍。我已經註冊的自定義ILifetimeScopeProviderAutofac終身使用範圍註冊共享,集成測試設置

public class TestLifetimeScopeProvider : ILifetimeScopeProvider 
{ 
    readonly ILifetimeScope container; 
    private ILifetimeScope lifetimeScope = null; 
    private ILifetimeScope testlifeScope = null; 

    public TestLifetimeScopeProvider(ILifetimeScope container) 
    { 
     if (container == null) throw new ArgumentNullException("container"); 
     this.container = container; 
    } 

    public ILifetimeScope ApplicationContainer 
    { 
     get { return container; } 
    } 

    public ILifetimeScope GetLifetimeScope() 
    { 
     if (lifetimeScope == null) 
     { 
      lifetimeScope = ApplicationContainer.BeginLifetimeScope("AutofacWebRequest"); 
     } 

     if (testlifeScope == null) 
     { 
      testlifeScope = lifetimeScope.BeginLifetimeScope("TestLifeScope"); 
     } 

     return testlifeScope; 
    } 

    public ILifetimeScope GetLifetimeScope(Action<ContainerBuilder> configurationAction) 
    { 
     return GetLifetimeScope(); 
    } 

    public void EndLifetimeScope() 
    { 
     if (lifetimeScope != null) 
      lifetimeScope.Dispose(); 
    } 

    public void EndTestLifetimeScope() 
    { 
     if (lifetimeScope != null) 
     { 
      testlifeScope.Disposer.Dispose(); 
      lifetimeScope = null; 
     } 
    } 
} 

這是從靜態構造函數

static TestBase() 
    { 
     var builder = new ContainerBuilder(); 
     DependencyRegistrar.Register(builder); 

     Container = builder.Build(); 

     LsProvider = new TestLifetimeScopeProvider(Container); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(Container, LsProvider)); 


    } 

DependencyRegistrar.Register(製造商)調用;保存所有初始註冊

,並具有在每個測試設置

builder.Register(c => mockInitializer.ServiceMock) 
          .As(mockInitializer.ServiceType) 
          .InstancePerMatchingLifetimeScope("TestLifeScope"); 
builder.Update(Container); 

也是我對TearDown中

[TearDown] 
    public virtual void TearDown() 
    { 
     LsProvider.EndTestLifetimeScope(); 
    } 

但事情處置邏輯註冊新的模擬一些模擬創建邏輯是,即使孩子範圍在每次測試後被處理,所有註冊都停留在主容器中。所以當我運行測試時,服務實現不應該被嘲笑,並且在此接口上的以前的測試中有一些模擬註冊,它會被使用。

我不能在每個測試設置建集裝箱,因爲我的父類的測試恢復,從而造成交易我需要建立在靜態構造容器先運行,以解決所有IRepository接口等

我也曾嘗試BeginLifetimeScope (C => ...)技術,但也沒有成功

任何想法的人? 謝謝

p.s.我使用Autofac 3.0.1版本 和MVC 4

回答

0

其實我已經來到辦法做到這一點(不知道這是否正確的方法,但它的工作原理)

要將TestLifeScopeProvider添加這些方法:

public void SetTestLifeTimeScope(ILifetimeScope lifeTimeScope) 
    { 
     testlifeScope = lifeTimeScope; 
    } 

    public ILifetimeScope GetLifetimeScope() 
    { 
     if (lifetimeScope == null) 
     { 
      lifetimeScope = ApplicationContainer.BeginLifetimeScope("AutofacWebRequest"); 
     } 

     return testlifeScope ?? lifetimeScope; 
    } 

要將TestBase設置添加以下代碼:

public void SetupServiceMocks() 
    { 
     if (ServiceMocks.Any()) 
     { 
      var currentLifeScope = LsProvider.GetLifetimeScope(); 
      var newScope = currentLifeScope.BeginLifetimeScope(builder => 
       { 
        foreach (var mockInitializer in ServiceMocks) 
        { 
         if (mockInitializer.ServiceType != null) 
         { 
          builder.Register(c => mockInitializer.ServiceMock) 
             .As(mockInitializer.ServiceType) 
             .InstancePerLifetimeScope(); 
         } 
        } 
       }); 

      LsProvider.SetTestLifeTimeScope(newScope); 
     } 
    } 

    [TearDown] 
    public virtual void TearDown() 
    { 
     LsProvider.EndTestLifetimeScope(); 
    } 

希望這有助於脫穎而出有人來節省一些時間和頭痛:)

+0

我有同樣的問題,但這種解釋是不完整的。你可以編輯這個併發布你所有的代碼嗎? – r3plica