如何绕过 HTTPContext 使用?
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 为空,因为我只是单元测试,我还没有经过身份验证。因此不会填充 HTTPContext 对象。
我无法对此类设定期望,因为 HTTPContext 是密封的。
我一直在网上搜索,但只有伪造 HTTPContextBase 的示例
现在我如何让我的单元测试通过。有什么建议吗?
谢谢,
维杰
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();
Now this Foo() Method contains the Following API Call
HttpContext.GetGlobalResourceObject(...,..);
But the HTTPContext is null, as i'm just unit testing , i have not Authenticated. and hence not populated the HTTPContext Object.
I cant set expectations on this class because the HTTPContext is sealed.
I've been searching in the net , but there were only samples to fake the HTTPContextBase
Now how do i get my Unit Test to Pass. Any Suggestions.?
thanks ,
vijay
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是您没有对“中心”方法设定期望。当您模拟对象时,所有实现都将替换为 Noop,直到您使用 Expectation 另行指定。
我猜您嘲笑的是
GetValueFromResource
而不是Centres
,因为Centres
调用GetValueFromResource
。如果是这种情况,模拟GetValueFromResource
可能是多余的假,您不需要它。另外,正如其他几篇 Moq 帖子中所指出的那样,您需要确保您没有嘲笑您正在测试的内容。如果您实际上正在尝试测试 MyController,您会想要模拟它具有的任何依赖项,但不是 MyController 本身。这会给你带来无尽的困惑。
编辑
根据此反馈,您似乎已经了解到真正的问题是您需要模拟 HTTPContext。模拟 HTTPContext 并非易事。有一些工具可以本地完成此操作,例如 Type Mock,但问题是环境上下文不可测试。
您应该做的是请求依赖关系,这些依赖关系为您提供所需的信息,同时抽象出它们的实现。例如,在您的情况下,您似乎正在使用 HTTPContext 来访问资源。如果您需要这样的东西,您可以使用的良好接口是:
您的默认实现将使用 HTTPContext,但现在您有一个可以模拟并让您的 MyController 类使用的接口,而不是直接使用 HTTPContext。
希望这有帮助。
The problem is you are not setting up an expectation for the "Centres" method. When you mock an object all implementations are replaced with a Noop until you specify otherwise using an Expectation.
I'm guessing you mocked
GetValueFromResource
rather thanCentres
becauseCentres
callsGetValueFromResource
. If this is the case, mockingGetValueFromResource
is likely a superfluous fake and you don't need it.Also, as has been pointed out on several other Moq posts, you'll need to make sure that you are not mocking what you are testing. If you are actually trying to test MyController, you'd want to mock any dependencies it has, but not MyController itself. This will cause you no end of confusion.
Edit
Based on this feedback it seems you have learned that your true problem is that you need to mock HTTPContext. Mocking HTTPContext is nontrivial. There are a few tools that can do it natively, like Type Mock, but the problem is that ambient context is not testable.
What you should be doing is requesting dependencies that give you the information you need while abstracting away their implementation. For example, in your case it seems like you are using HTTPContext to access resources. If you need something like this a good interface you could use would be:
Your default implementation would use HTTPContext, but now you have an interface you can mock and have your MyController class use, rather than HTTPContext directly.
Hope this helps.