在C#中的单元测试中使用测试类模拟实现类

时间:2015-03-04 18:51:28

标签: c# unit-testing interface dependency-injection moq

我正在尝试编写一个简单的单元测试,其中包含了HttpContext.Current.Server.MapPath以及接口和实现。如果实施在正确的位置,我不肯定。

public class FooGenerator
{
    ServerPathProvider serverPathProvider = new ServerPathProvider();

    public string generateFoo()
    {
        BarWebService bws = new BarWebService(serverPathProvider.MapPath("~/path/file"));
        return stuff;
    }
}


public class ServerPathProvider : IPathProvider
{
    public string MapPath(string path)
    {
        return HttpContext.Current.Server.MapPath(path);
    }
}

在测试中我有自己想要使用的实现,但是在单元测试期间我无法弄清楚如何将它注入到真正的类中。

[TestClass()]
public class FooGeneratorTests
{
    [TestMethod()]
    public void generateFooTest()
    {
        FooGenerator fg = new FooGenerator();

        //Some kind of mock dependency injection
        Mock<IPathProvider> provider = new Mock<IPathProvider>();
        //stub ServerPathProvider object with provider mock

        string token = fg.generateFoo;
        Assert.IsNotNull(token);
    }
}

public class TestPathProvider : IPathProvider
{
    public string MapPath(string path)
    {
        return Path.Combine(@"C:\project\", path);
    }
}

最后,这是我的界面以防万一。基本上我只想换掉两个实现,具体取决于我是否是单元测试。这是我的第一次单元测试,这对我来说很新。对不起,如果我遗漏了一些基本的东西,但我一直在挖掘堆栈溢出一段时间,但找不到执行此部分的步骤。

public interface IPathProvider
{
    string MapPath(string path);
}

1 个答案:

答案 0 :(得分:1)

有几个选择。

接受参数

一般情况下,您希望FooProvider的{​​{1}}成员变量为IPathProvider而不是ServicePathProvider

servicePathProvider可以有两个构造函数:

  1. 实例化FooProvider
  2. 的默认构造函数
  3. 实例化的非默认构造函数将servicePathProvider = new ServicePathProvider();作为参数,并将IServiceProvider设置为该参数。
  4. 通用类

    按如下方式更改servicePathProvider

    FooProvider

    在非单元测试代码中,您可以使用public class FooProvider<T> where T : IServiceProvider, new() ,对于单元测试,您可以使用FooProvider<ServicePathProvider>

    这使得FooProvider<Mock>接受通用类型FooProvider,它是T 的子类型,而具有默认构造函数(IServiceProvider new() 1}} part)在where子句中。