C# 如何模拟容器。解决(<;类型>;()
我有一个类似这样的想法C# 如何模拟容器。解决(<;类型>;(),c#,moq,ioc-container,C#,Moq,Ioc Container,我有一个类似这样的想法 public class HomeController { public ActionResult Index() { var x = Container.Resolve<IOrganisationService>(); } } 公共类HomeController { 公共行动结果索引() { var x=Container.Resolve(); } } 当单元测试时,当容器尝试解析时,我得到一个空引用异常 有人知道如何模拟C
public class HomeController
{
public ActionResult Index()
{
var x = Container.Resolve<IOrganisationService>();
}
}
公共类HomeController
{
公共行动结果索引()
{
var x=Container.Resolve();
}
}
当单元测试时,当容器尝试解析时,我得到一个空引用异常
有人知道如何模拟Container.Resolve()?问题是,为什么要以这种方式解决它?相反,如果注入依赖项,则可以轻松模拟:
public class HomeController
{
private readonly IOrganisationService organisationService;
public HomeController(IOrganisationService organisationService)
{
this.organisationService = organisationService;
}
public ActionResult Index()
{
var x = this.organisationService;
}
}
您不能,因为所讨论的Resolve方法是静态方法。这是在单元测试(以及代码的一般可组合性)中,静态类型被认为是邪恶的众多原因之一 您似乎正在应用一种称为服务定位器(ServiceLocator)的(反)模式,并且您当前正遇到与此相关的许多问题之一 更好的解决方案是使用构造函数注入,如下所示:
public class HomeController
{
private readonly IOrganisationService organisationService;
public HomeController(IOrganisationService organisationService)
{
if (organisationService == null)
{
throw new ArgumentNullException("organisationService");
}
this.organisationService = organisationService;
}
public ActionResult Index()
{
var x = this.organisationService;
// return result...
}
}
现在可以让您选择的DI容器从外部解析HomeController实例。这是一个更加灵活的解决方案。一些容器(例如Windsor)具有从接口继承的容器。如果您使用这个,那么它是隐式可模仿的。如果您已经创建了一个可以调用resolve的静态方法,那么如上所述,不建议对其进行模拟。如果您的容器不是从依赖静态方法的接口(或您正在使用的服务定位器模式)继承的,那么请更改实现,使其基于实例,因此是可模拟的
然而,我同意上面的帖子。您不应该真的需要从代码中引用容器。这会将您的应用程序耦合到一个容器,而容器是您试图通过使用容器来避免的事情之一 我做到了,就像这样:
//code inside the setup method
var c = new Moq.Mock<IWindsorContainer>();
var l = new Moq.Mock<ILookupService>();
l.Setup(o => o.GetItems(It.IsAny<String>())).Returns(new List<LookupItem>());
c.Setup(o => o.Resolve<ILookupService>()).Returns(l.Object);
LocatorConfigurator.SetContainer(c.Object);
//安装方法中的代码
var c=新的最小起订量Mock();
var l=新的最小起订量。模拟();
l、 Setup(o=>o.GetItems(It.IsAny()).Returns(newlist());
c、 设置(o=>o.Resolve())。返回(l.Object);
LocatorConfigurator.SetContainer(c.Object);
你用什么做容器?不,不是那样的,我只是想简化一下,实际上我需要它way@Omu当前位置你为什么需要它?我会尽量避免这种情况,并使用上面马克和肯特展示的内容。