我有一个控制器的两个测试用例。我想确保每个测试用例都接收一个唯一的Session实例,以便模拟InstancePerWebApiRequest。我当前的实现是有缺陷的,因为它适用于多个测试用例中的单个ISession实例。但是,如果我在一个测试用例之后处理了Scope,那么即使我已经从Autofac重新请求了一个新的,我被告知我的Session已经关闭。
这就是我所拥有的:
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中实例化一次我的Scope。如果我在每个测试用例之后处理我的作用域(在TearDown中),那么我的第二个测试用例会抛出一个异常,表明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);
}
}
答案 0 :(得分:1)
这有点similar/related to your other question关于获取每个请求的范围。 The answer here is the same as before - 您需要使用HttpRequestMessage
来管理生命周期范围。这意味着从生命周期范围中解析您的控制器,这将反过来解决注册为InstancePerApiRequest
的所有依赖项。
另外,正如前面的回答所提到的,我真的远离设置全局静态变量(全局依赖解析器)。在设置静态时,你可能真的搞乱了测试环境,并且奇怪/难以重现问题或间歇性失败。