如何绕过HTTPContext用法。?

时间:2009-09-21 09:26:10

标签: asp.net-mvc tdd mocking moq

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

现在如何让我的单元测试通过。任何建议。?

谢谢,

维杰

1 个答案:

答案 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

希望这有帮助。