Search code examples
c#modulemockingmoqshim

How to mock out the server transfer method using shims and or Moq


I am trying to mock up the following Transfer request.

I have tried using Moq but it doesn't like the fact that it is a method call. Any ideas?

I have tried using shims but it hasn't exactly made sense to me. https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e423407-300d-46ba-bfc9-30465fb18f07/how-to-fake-httpcontextcurrent-using-shim?forum=vstest I tried mocking http context this way but it didn't work either. 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
    }

Solution

  • Similar to an approach I took in an answer provided here

    How to test HttpApplication events in IHttpModules

    You can create a factory method/function that wraps the current tightly coupled implementation concerns in abstractions that would allow for better mocking and testability

    Refactored module

    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
        }
    
        //...
    }
    

    The GetContext factory function can be replaced when testing to use a mock.

    For example

    [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);
    }