如何绕过 HTTPContext 使用?

发布于 2024-08-05 11:55:19 字数 616 浏览 3 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅笑轻吟梦一曲 2024-08-12 11:55:19

问题是您没有对“中心”方法设定期望。当您模拟对象时,所有实现都将替换为 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

希望这有帮助。

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 than Centres because Centres calls GetValueFromResource. If this is the case, mocking GetValueFromResource 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:

public interface IResourceStore
{
     object GetGlobalResource(string  classKey, string resourceKey);
}

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.

Mock<IResourceStore> resourceStore = new Mock<IResourceStore>();
//setup resourceStore expectations here

MyController testingTarget = new MyController(_Service, resourceStore.Object);
//target assertions here

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文