如何使用Moq模拟内部类保护方法?

时间:2015-09-05 14:49:34

标签: unit-testing moq

我有以下课程:

public class TestService
{
     public void Upload()
     {
        var manager = new Manager();
        var worker = manager.CreateWorker();
        worker.DoWork();
     }
}

public class Manager
{
    public Worker CreateWork()
    {
        return new Worker();
    }
}

public class Worker()
{
     public void DoWork()
     {
        SetupEnvironment();
        //some codes here...
     }

     protected virtual void SetupEnvironment()
     {
       //some codes here ...
     }
}

我想使用Moq为TestService类中的Upload()方法创建单元测试,而Worker的SetupEnvironment()方法应该是模拟的。我尝试了下面的代码,但它不起作用:

[TestMethod]
public void Upload_Test()
{
        var mockWorker = new Mock<Worker>();
        mockWorker .Protected().Setup<string>("SetupEnvironment").Returns(() =>
        {
            //some dummy code here ...
        });

        var service = new TestService();
        service.Upload();
        Assert.IsTrue(true);
  } 

有谁知道如何使上述单元测试代码有效?

1 个答案:

答案 0 :(得分:0)

有些事情需要改变。请参阅下面的课程TestServiceWorker的代码。

public class TestService
{
    private readonly Manager _manager;

    public TestService(Manager manager)
    {
        _manager = manager;
    }

    public void Upload()
    {
        var worker = _manager.CreateWorker();
        worker.DoWork();
    }
}

public class Manager
{
    public virtual Worker CreateWorker()
    {
        return new Worker();
    }
}

public class Worker
{
    public void DoWork()
    {
        SetupEnvironment();
        //some codes here...
    }

    protected virtual void SetupEnvironment()
    {
        //some codes here ...
    }
}

然后测试看起来像这样。方法SetupEnvironmentvoid,因此设置无法返回任何值,您还需要模拟Manager并将其传递给TestService,例如[TestMethod] public void Upload_Test() { bool setupEnvironmentWasCalled = false; Mock<Worker> mockWorker = new Mock<Worker>(); mockWorker.Protected().Setup("SetupEnvironment") .Callback(() => { //some dummy code here ... setupEnvironmentWasCalled = true; }); Mock<Manager> mockManager = new Mock<Manager>(); mockManager.Setup(m => m.CreateWorker()) .Returns(mockWorker.Object); var service = new TestService(mockManager.Object); service.Upload(); Assert.IsTrue(setupEnvironmentWasCalled); } 。通过构造函数注入,这样你就可以注入你的模拟对象了。 HTH

{{1}}