如何在未声明为虚拟

时间:2016-08-18 12:49:46

标签: c# unit-testing moq

我正在尝试为C#项目创建一个单元测试,其中我有一个我无法修改的外部类。它不是从Interface实现的,方法也不是虚拟的。

我想模拟从此类的方法返回的结果以及该方法将设置的任何类属性。

所以我在外部课

 public class RatioThreadProcessor {
    public SqlString dbName;        
    public List<Instrument> units;
    public Results Results;
    etc
    public void Process() {

        // Does stuff 
        // I want this to be called for real but not in my test case
    }

我正在测试的代码是这样的:

public class FundInfoRatioService
{
    public RatioThreadProcessor ratioThreadProcessor;

    public FundInfoRatioService()
    {
        ratioThreadProcessor = new RatioThreadProcessor();
    }

    public MethodUnderTest() 
    {
       ratioThreadProcesor.dbName = "as";
       ratioThreadProcessor.Process();
       var results = ratioThreadProcessor.Results;
       // important logic I want to test
    }

并测试它我想做类似的事情:

  public class MockRatioThreadProcessor : RatioThreadProcessor
  {
       public new void Process()
       { 
           // mock Logic
           // I want this to be called in my test case
       }
  }      

  private Mock<RatioThreadProcessor> mockRatioThreadProcessor;
  public void SetUp()
  {
      mockRatioThreadProcessor = new Mock<MockRatioThreadProcessor();
      mockRatioThreadProcessor.SetUp(r => r.Process());
  }
  public void TestMethod()
  {
      var fundInfoRatioService = new FundInfoRatioService(null);          
      fundInfoRatioService.ratioThreadProcessor = mockRatioThreadProcessor.Object;
      fundInfoRatioService.MethodUnderTest();
      // assert results
  }

我遇到的问题是总是调用基本的Process方法而不是我想要调用的模拟的方法。

我认为它是因为C#将始终调用声明它的变量的方法,即使它已被初始化为继承的。

关于如何进行此测试并模拟外部类的Process方法的任何想法?

由于

1 个答案:

答案 0 :(得分:4)

您可以采取的一种方法是围绕RatioThreadProcessor创建一个包装类:

class RatioThreadProcessorWrapper : IThreadProcessor
{
    private readonly RatioThreadProcessor _ratioThreadProcessor;

    public RatioThreadProcessorWrapper ()
    {
        _ratioThreadProcessor = new RatioThreadProcessor();
    }

    public Process() => ratioThreadProcessor.Process();
    ...
}

将其(通过参考IThreadProcessor)注入FundInfoRatioService

但是,值得查看MethodUnderTest方法。这个方法:

  1. 修改RatioThreadProcessor
  2. 的实例
  3. 致电Process
  4. 获取一些结果,
  5. 与结果有关。
  6. 所以你有一种做四件事的方法。如果你移动方法的前三个并让它只有(4)的单一责任,那么你可以传入一个测试结果对象并以这种方式测试你的方法,将它与RatioThreadProcessor分开。