Home > Blockchain >  Add dependency injection for server.mappath
Add dependency injection for server.mappath

Time:05-26

I'm new at Unit test and try to add a dependency injection for Server.MapPath, this is what I have so far...

IPathMapper

    public interface IPathMapper
{
    string MapPath(string relativePath);
}

ServerPathMapper

    public class ServerPathMapper : IPathMapper
{
    public string MapPath(string relativePath)
    {
        return HttpContext.Current.Server.MapPath(relativePath);
    }
}

DummyPathMapper

    public class DummyPathMapper : IPathMapper
{
    public string MapPath(string relativePath)
    {
        return "C:/temp/"   relativePath;
    }
}

Test

    [Fact]
    public void Add_InvoiceViewModel_ToUploadActionResult()
    {
        // Arrange
        var serverPathMapper = new DummyPathMapper();
        var myController = new InvoiceController();
        var mockClaim = new Claim("Administrator", "test");

        var identity = Substitute.For<ClaimsIdentity>();
        identity.Name.Returns("test name");
        identity.IsAuthenticated.Returns(true);
        identity.FindFirst(Arg.Any<string>()).Returns(mockClaim);

        var claimsPrincipal = Substitute.For<ClaimsPrincipal>();
        claimsPrincipal.HasClaim(Arg.Any<string>(), Arg.Any<string>()).Returns(true);
        claimsPrincipal.HasClaim(Arg.Any<Predicate<Claim>>()).Returns(true);
        claimsPrincipal.Identity.Returns(identity);

        var httpContext = Substitute.For<HttpContextBase>();
        httpContext.User.Returns(claimsPrincipal);
        

        var controllerContext = new ControllerContext(
            httpContext, new System.Web.Routing.RouteData(), myController);

        myController.ControllerContext = controllerContext;
        myController._pathMapper = new DummyPathMapper();

        
        var model = new InvoiceViewModel
        {
            InvoiceInfoNotice = "",
            InvoiceList = new List<Bill>()
        };

        var constructorInfo = typeof(HttpPostedFile).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
        var obj = (HttpPostedFile)constructorInfo
            .Invoke(new object[] { @"D:\file.xlsx", "application/vnd.ms-excel", null });

        model.MembershipRegisterFile = new HttpPostedFileWrapper(obj);


        // Act
        var actionResult = myController.Upload(model, "");

        // Assert
        actionResult.Should().NotBeNull();
    }

Where and how Do I add the DummyPathMapper in Arrange?

UPDATE: I added this, is this the correct way?

Controller

public IPathMapper _pathMapper;

public InvoiceController()
{
    _pathMapper = new ServerPathMapper();
}

CodePudding user response:

IPathMapper should be injected into the controller as an explicit dependency via constructor injection.

//...

private readonly IPathMapper pathMapper;

//ctor
public InvoiceController(IPathMapper pathMapper) {
    this.pathMapper = pathMapper;
}

//...

Assuming DI is being used in your application and it has been configured correctly, then ServerPathMapper will be injected at run-time.

This will now allow for the test to be arranged accordingly

//...

// Arrange
var serverPathMapper = new DummyPathMapper();
var myController = new InvoiceController(serverPathMapper);

//...
  • Related