g18*_*18c 7 c# unit-testing dependency-injection simple-injector membus
我正在使用Microsoft Unit Test并具有以下内容:
public class AccountCommandHandlers :
Handler<CreateAccountCommand>,
Handler<CloseAccountCommand>
{
public bool CreateAccountCommandWasCalled = false;
public bool CloseAccountCommandWasCalled = false;
public void Handle(CreateAccountCommand command)
{
CreateAccountCommandWasCalled = true;
}
public void Handle(CloseAccountCommand command)
{
CloseAccountCommandWasCalled = true;
}
}
[TestMethod]
public void CanRaiseInternalHandlers()
{
var iocContainer = SimpleInjectorWiringForMembus.Instance;
iocContainer.Bootstrap(
AppDomain.CurrentDomain.GetAssemblies());
var membus = MembusWiring.Instance;
membus.Bootstrap();
membus.Bus.Publish(new CreateAccountCommand() { Id = 100 });
membus.Bus.Publish(new CloseAccountCommand() { Id = 100 });
}
Run Code Online (Sandbox Code Playgroud)
我正在使用IoC容器(Simple Injector)来处理对象的生命周期范围.Membus将命令连接到命令处理程序,并通过IoC容器解析.
上面的代码运行并运行,命令处理程序将其局部变量设置为true.
但是,由于Simple Injector处理生命周期范围,我无法向Simple Injector请求一个AccountCommandHandler对象,因为它会返回一个CreateAccountCommandWasCalled设置为false 的新对象.
作为单元测试的新手,除了设置CreateAccountCommandWasCalled为静态变量之外,还有什么更强大的测试方法?
正如其他人已经提到的那样,您实际上正在运行集成测试.然而,这不是问题.集成测试适用于测试IoC设置并确保应用程序的不同部分协同工作.
但是,通过集成测试,您不应该使用mock或stub对象.模拟和存根在单元测试中有其用途.单元测试就是测试代码中最小的部分.在单元测试中,您使用模拟来控制您的类具有的所有依赖项的行为.我在一年前写了一篇博客,介绍了集成和单元测试之间的差异以及如何在测试中使用模拟.
在您的情况下,我不会使用具有生产配置的IoC容器来设置单元测试.相反,我会切换到在测试中手动创建对象,并使用像Moq这样的模拟工具来控制依赖项.
但这也是可以自动化的.一个很棒的工具是AutoFixture."Fixture"指的是运行测试所需的基线.这可能是一些示例数据,您需要的模拟和存根以及其他设置代码.
几周前,Mark Seemann(AutoFixture背后的开发人员)写了一篇很好的博客,关于将AutoFixture与IoC一起用作自动模拟容器.我建议使用这样的东西来构建你的单元测试.
正如Steven在评论中所说,听起来您正在编写集成测试,在这种情况下,使用IoC容器确实有意义。
您的测试项目应具有自己的IoC配置组成根。您可以配置IoC容器以返回AccountCommandHandlers的模拟对象。您的测试可以检查Handle(CreateCommand)至少被调用一次,而不是检查布尔成员。使用Moq,它看起来像这样:
mock.Verify(foo => foo.Handle(createAccountCommand), Times.AtLeastOnce());
Run Code Online (Sandbox Code Playgroud)
如果出于某种原因您不能在IoC配置中使用模拟框架,则很容易为此一个测试用例创建自己的模拟类。
| 归档时间: |
|
| 查看次数: |
1719 次 |
| 最近记录: |