如何模拟container.Resolve()
当单元测试时,我有一个类似的东西,
public class HomeController
{
public ActionResult Index()
{
var x = Container.Resolve<IOrganisationService>();
}
}
当容器尝试解析时,我得到一个空引用异常
有人知道如何模拟 Container.Resolve() 吗?
i have a something like this
public class HomeController
{
public ActionResult Index()
{
var x = Container.Resolve<IOrganisationService>();
}
}
when unit testing i get a null reference exception when the container tries to resolve
anybody knows how do to mock Container.Resolve() ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不能,因为所讨论的 Resolve 方法是静态方法。这是在单元测试(以及代码的一般可组合性)方面静态类型被认为是“邪恶”的众多原因之一。
您似乎正在应用一种称为“服务定位器”的(反)模式,并且您当前正在遇到与其相关的众多问题之一。
更好的解决方案是使用构造函数注入,如下所示:
您现在可以让您选择的 DI 容器从外部解析 HomeController 实例。这是一个更加灵活的解决方案。
You can't, because the Resolve method in question is a static method. This is one of the many reasons static types are considered evil when it comes to unit testing (and hence for general composability of code).
You seem to be applying an (anti)pattern known as Service Locator, and you are currently experiencing one of the many problems associated with it.
A better solution would be to use Constructor Injection like this:
You can now let your DI Container of choice resolve the HomeController instance from the outside. This is a much more flexible solution.
问题是,你为什么要以这种方式解决它?如果您注入了依赖项,那么您可以轻松模拟:
The question is, why are you resolving it in that fashion? If you instead have the dependency injected, then you can easily mock:
某些容器(例如 Windsor)具有从接口继承的容器。如果您使用它,那么它是隐式可模拟的。如果您创建了一个可以调用解析的静态方法,那么如上所述,不建议对其进行模拟。如果您的容器不继承自接口(或您正在使用的服务定位器模式),则依赖于静态方法,然后更改实现,使其基于实例并因此可模拟。
不过,我同意上面的帖子。您实际上不需要从代码中引用容器。这将您的应用程序与容器耦合在一起,这是您通过使用容器试图避免的事情。
Some containers (Windsor for example) have a container which inherits from an interface. If you use this then it is implicitly mockable. If you have created a static method that you can call resolve on, then as stated above it cannot be mocked isn't advisable. If your container doesn't inherit from an interface (or the service locator pattern you are using) relies on a static method then change the implementation so it's instance based and therefore mockable.
However, I agree with the posts above. You shouldn't really need to reference your container from within your code. This couples your application to a container which is of the things you are trying to avoid by using a container.
我做到了,是这样的:
I did it, it's like this: