为 server.mappath 添加依赖注入

Add dependency injection for server.mappath

我是单元测试的新手,尝试为 Server.MapPath 添加依赖注入,这就是我目前所拥有的...

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

测试

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

我在哪里以及如何在 Arrange 中添加 DummyPathMapper?

更新:我添加了这个,这是正确的方法吗?

控制器

public IPathMapper _pathMapper;

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

IPathMapper 应该通过构造函数注入作为显式依赖注入到控制器中。

//...

private readonly IPathMapper pathMapper;

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

//...

假设 DI 正在您的应用程序中使用并且已正确配置,那么 ServerPathMapper 将在 run-time.

处注入

现在可以相应地安排测试

//...

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

//...