【问题标题】:How to mock out the server transfer method using shims and or Moq如何使用 shims 和/或 Moq 模拟服务器传输方法
【发布时间】:2019-06-08 22:58:08
【问题描述】:

我正在尝试模拟以下传输请求。

我尝试过使用 Moq,但它不喜欢它是一个方法调用这一事实。有任何想法吗?

我尝试过使用 shims,但它对我来说并不完全有意义。 https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e423407-300d-46ba-bfc9-30465fb18f07/how-to-fake-httpcontextcurrent-using-shim?forum=vstest 我尝试以这种方式模拟 http 上下文,但它也不起作用。 https://justinchmura.com/2014/06/26/mock-httpcontext/

public class MyModule1 : IHttpModule
{
    /// <summary>
    /// You will need to configure this module in the Web.config file of your
    /// web and register it with IIS before being able to use it. For more information
    /// see the following link: https://go.microsoft.com/?linkid=8101007
    /// </summary>
    #region IHttpModule Members

    public void Dispose()
    {
        //clean-up code here.
    }

    public void Init(HttpApplication context)
    {
        // Below is an example of how you can handle LogRequest event and provide 
        // custom logging implementation for it
        context.LogRequest += new EventHandler(OnLogRequest);
        context.BeginRequest += new EventHandler(OnBeginRequest);
    }

    private void OnBeginRequest(object sender, EventArgs e)
    {
        onbegin(new HttpContextWrapper(((HttpApplication)sender).Context));


    }

    private void onbegin(HttpContextBase context)
    {
        // other header stuff goes here
        context.Server.TransferRequest("bobsyouruncle", true);
    }

    #endregion

    public void OnLogRequest(Object source, EventArgs e)
    {
        //custom logging logic can go here
    }

【问题讨论】:

  • 因为您在模块中使用具体类(即 HttpApplication)并且它们都是密封的,没有 Microsoft Fakes,您真的很不走运。如果您可以像在 onbegin 方法中那样切换为使用更现代的 HttpContextBase 等,您可以模拟这些。

标签: c# module mocking moq shim


【解决方案1】:

类似于我在此处提供的答案中采用的方法

How to test HttpApplication events in IHttpModules

您可以创建一个工厂方法/函数,将当前紧密耦合的实现问题封装在抽象中,从而实现更好的模拟和可测试性

重构模块

public class MyModule1 : IHttpModule {
    public void Dispose() {
        //clean-up code here.
    }

    public void Init(HttpApplication application) {
        // Below is an example of how you can handle LogRequest event and provide 
        // custom logging implementation for it
        application.LogRequest += new EventHandler(OnLogRequest);
        application.BeginRequest += new EventHandler(OnBeginRequest);
    }

    public Func<object, HttpContextBase> GetContext = (object sender) => {
        return new HttpContextWrapper(((HttpApplication)sender).Context);
    };

    public void OnBeginRequest(object sender, EventArgs e) {
        var context = GetContext(sender);
        onbegin(context);
    }

    private void onbegin(HttpContextBase context) {
        // other header stuff goes here
        context.Server.TransferRequest("bobsyouruncle", true);
    }

    public void OnLogRequest(Object source, EventArgs e) {
        //custom logging logic can go here
    }

    //...
}

GetContext 工厂函数可以在测试使用模拟时被替换。

例如

[TestMethod]
public void Server_Should_Transfer() {
    //Arrange
    var server = new Mock<HttpServerUtilityBase>();
    var context = new Mock.<HttpContextBase>();
    context.Setup(_ => _.Server).Returns(server.Object);

    var sut = new MyModule1();

    //replace with mock context for test
    sut.GetContext = (object sender) => context.Object;

    //Act
    sut.OnBeginRequest(new object(), EventArgs.Empty);

    //Assert
    server.Verify(_ => _.TransferRequest("bobsyouruncle", true), Times.AtLeastOnce);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2010-11-12
    相关资源
    最近更新 更多