【问题标题】:Moq. Mock system class起订量。模拟系统类
【发布时间】:2016-05-04 07:29:44
【问题描述】:

我收到一个旧项目并开始重构它以用于 SUT。我使用 Moq 和 NUnit 框架。我在这个项目中遇到了下一节课:

public ServerRunner()
{
    Name = ConfigurationManager.AppSettings["ServiceName"];

    WinService = new ServiceController(Name);
    logger = new Logger.Logger(Name);

    syncRoot = new ReaderWriterLockSlim();
    timeoutMilliseconds = 10000;
}

我是单元测试领域的新手,所以我需要建议 - 如何提取和模拟 System.ServiceController 类?可以由 Moq 完成还是我应该使用其他一些 Mock 框架?

【问题讨论】:

    标签: c# unit-testing tdd moq


    【解决方案1】:

    如果你想模拟 ServiceController 我会把它放在一个接口后面。例如,

    interface IControlServices {
      // ... methods you want to implement
    }
    
    class MyServiceController {
      private ServiceController _serviceController;
    
      public MyServiceController(ServiceController servicecontroller){
        _serviceController = servicecontroller;
      }
    
      // ... methods you want to implement from interface
    }
    

    然后使用依赖注入(不一定使用 DI 框架)将其放入您的 ServerRunner 类中。

    【讨论】:

    • 是否缺少代码类 MyServiceController : IControlServices 的部分?我不明白接口和具体类之间的关系。
    【解决方案2】:

    看起来ServiceController 不是一个简单的Moqable 类,但您始终可以执行以下操作:

    • 将该类中您需要的功能封装到另一个自定义类中(比如ServiceControllerWrapper)。
    • 提取界面 (IServiceControllerWrapper)。
    • IServiceControllerWrapper 实例传递给ServerRunner 的构造函数并在类中使用该实例。
    • 然后您可以测试ServerRunner 类,将IServiceControllerWrapper 接口的Moq 作为参数传递给构造函数。

    看起来像这样:

    public ServerRunner(IServiceControllerWrapper controllerInstance)
    {
        Name = ConfigurationManager.AppSettings["ServiceName"];
    
        WinService = controllerInstance;
        logger = new Logger.Logger(Name);
    
        syncRoot = new ReaderWriterLockSlim();
        timeoutMilliseconds = 10000;
    }
    

    希望这会有所帮助!

    【讨论】:

    • 谢谢。有自己的想法,所以我会尝试一下
    猜你喜欢
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    相关资源
    最近更新 更多