2014-03-19 36 views
0

我有兩個控制器測試用例。我想確保每個測試用例都在接收一個唯一的Session實例,以模擬InstancePerWebApiRequest。我當前的實現有缺陷,因爲它在多個測試用例中與單個ISession實例一起工作。但是,如果我在一個測試用例後處理範圍,那麼即使我已經重新請求Autofac提供了一個新的測試用例,我仍然被告知我的會話已關閉。爲測試用例內的InstancePerApiRequest生成一個ISession

下面是我得到了什麼:

public class AutofacRegistrations 
{ 
    public static void RegisterAndSetResolver() 
    { 
     var containerBuilder = new ContainerBuilder(); 

     containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 

     // Per Design Patterns: Elements of Reusable Object-Oriented Software - an abstract factory is often used as a singleton. 
     containerBuilder.Register(x => new NHibernateConfiguration().Configure().BuildSessionFactory()).SingleInstance(); 
     containerBuilder.RegisterType<NHibernateDaoFactory>().As<IDaoFactory>().SingleInstance(); 
     containerBuilder.RegisterType<StreamusManagerFactory>().As<IManagerFactory>().SingleInstance(); 

     // Everything else wants an instance of Session per API request, so indicate that: 
     containerBuilder.Register(x => x.Resolve<ISessionFactory>().OpenSession()).InstancePerApiRequest(); 
     containerBuilder.Register(x => LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType)).InstancePerApiRequest(); 

     ILifetimeScope container = containerBuilder.Build(); 

     var dependencyResolver = new AutofacWebApiDependencyResolver(container); 
     GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; 
    } 
} 

下面我宣佈我的工廠爲單身人士和指示,我想每個API請求一個ISession。

這裏是我的設置我的測試方法如下:

public abstract class StreamusTest 
{ 
    protected ILog Logger; 
    protected IDaoFactory DaoFactory; 
    protected IManagerFactory ManagerFactory; 
    protected Helpers Helpers; 
    protected ISession Session; 

    private IDependencyScope Scope; 

    [TestFixtureSetUp] 
    public void TestFixtureSetUp() 
    { 
     StreamusWebApi.InitializeApplication(); 

     // TODO: I feel like this is incorrect because Session is only generated once. Shouldn't it be SessionPerTestCase? 
     Scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope(); 

     Logger = (ILog)Scope.GetService(typeof(ILog)); 
     DaoFactory = (IDaoFactory)Scope.GetService(typeof(IDaoFactory)); 
     ManagerFactory = (IManagerFactory)Scope.GetService(typeof(IManagerFactory)); 
     Session = (ISession)Scope.GetService(typeof(ISession)); 

     Helpers = new Helpers(Logger, Session, ManagerFactory); 
    } 

    [SetUp] 
    public void SetUp() 
    { 
     // TODO: I think I want to be generating a Scope per SetUp and dispose of it in TearDown. 
     // Scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope(); 
     // Logger = (ILog)Scope.GetService(typeof(ILog)); 
     // Session = (ISession)Scope.GetService(typeof(ISession)); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     // Scope.Dispose(); 
    } 

    [TestFixtureTearDown] 
    public void TestFixtureTearDown() 
    { 
     Scope.Dispose(); 
    } 
} 

我覺得這是不正確,因爲我只在TestFixtureSetup實例我曾經範圍。如果我在每個測試用例(在TearDown中)後處理我的作用域,那麼我的第二個測試用例會拋出一個異常,指出Session已關閉。

我相信我的當​​前實現在我的所有測試用例中使用單個Session,這是不正確的。任何人都可以提供一些關於如何正確設置的建議?

這裏是我的實際測試的情況下,以供參考:

[TestFixture] 
public class ClientErrorControllerTest : StreamusTest 
{ 
    private ClientErrorController ClientErrorController; 

    [SetUp] 
    public new void TestFixtureSetUp() 
    { 
     ClientErrorController = new ClientErrorController(Logger, Session, ManagerFactory); 
    } 

    [Test] 
    public void CreateError_ShortMessage_ErrorCreated() 
    { 
     var clientErrorDto = new ClientErrorDto 
      { 
       Message = "Hello World", 
       ClientVersion = "0.99", 
       LineNumber = 2 
      }; 

     ClientErrorDto createdErrorDto = ClientErrorController.Create(clientErrorDto); 
     Assert.NotNull(createdErrorDto); 
    } 

    [Test] 
    public void CreateError_LongMessage_MessageTruncatedErrorCreated() 
    { 
     var clientErrorDto = new ClientErrorDto 
      { 
       Message = 
        "Hello World This is a Really Long Message Which is going to be over 255 characters in length when finished which will cause the end result message to be truncated with three periods as to not overflow the database. Can I confirm that this is happening? Thanks", 
       ClientVersion = "0.99", 
       LineNumber = 2 
      }; 

     ClientErrorDto createdErrorDto = ClientErrorController.Create(clientErrorDto); 

     Assert.NotNull(createdErrorDto); 
     Assert.That(createdErrorDto.Message.Length == 255); 
    } 
} 

回答

1

這個有點similar/related to your other question有關獲取每個請求的範圍出現。 The answer here is the same as before - 您需要使用HttpRequestMessage來管理生命週期範圍。這意味着解決你的控制器從生命週期的範圍,這將依次解決註冊爲InstancePerApiRequest的所有依賴關係。另外,正如前面的答案中提到的,我真的不想設置全局靜態變量(全局依賴關係解析器)。當你設置靜態的時候,你可能真的搞砸了一個測試環境,並且奇怪/難以重現問題或間歇性故障。

相關問題