var mockedService = new Mock<IService>();
mockedService.Setup(x => x.InterfaceMethod(args)).Returns(value);
_Service = mockedService.Object;
MyController controller =new MyController(_Service);
var result = (ViewResult)controller.Foo();
现在这个Foo()方法包含以下API调用
HttpContext.GetGlobalResourceObject(...,..);
但HTTPContext为null,因为我只是单元测试,我没有经过身份验证。因此没有填充HTTPContext对象。
我无法对此课程设定期望,因为 HTTPContext 已被密封。
我一直在网上搜索,但只有样本可以伪造 HTTPContextBase
现在如何让我的单元测试通过。任何建议。?
谢谢,
维杰
答案 0 :(得分:1)
问题是你没有对“中心”方法设定期望。当您模拟对象时,所有实现都将替换为Noop,直到您使用Expectation指定其他方式。
我猜你曾嘲笑GetValueFromResource
而不是Centres
因为Centres
调用 GetValueFromResource
。如果是这种情况,嘲弄GetValueFromResource
可能是多余的假货,你不需要它。
另外,正如其他几个Moq帖子所指出的,你需要确保你没有嘲笑你正在测试的内容。如果您实际上是在尝试测试MyController,那么您需要模拟它具有的任何依赖项,而不是MyController本身。这将使您不会感到困惑。
修改强>
根据这些反馈,您似乎已经了解到您的真正问题是您需要模拟HTTPContext。模拟HTTPContext是非常重要的。有一些工具可以本机化,如Type Mock,但问题是环境上下文不可测试。
您应该做的是请求依赖项,这些依赖项会在抽象出其实现时为您提供所需的信息。例如,在您的情况下,您似乎正在使用HTTPContext来访问资源。如果你需要这样的东西,你可以使用的好界面是:
public interface IResourceStore
{
object GetGlobalResource(string classKey, string resourceKey);
}
您的默认实现将使用HTTPContext,但现在您有一个可以模拟并使用MyController类的接口,而不是直接使用HTTPContext。
Mock<IResourceStore> resourceStore = new Mock<IResourceStore>();
//setup resourceStore expectations here
MyController testingTarget = new MyController(_Service, resourceStore.Object);
//target assertions here
希望这有帮助。