使用Moq

时间:2019-03-13 09:27:41

标签: c# unit-testing moq

我有多个方法,它们具有多个thread.sleep,有时可持续20秒。这是一项业务要求。我试图通过模拟和跳过这些睡眠来对这些方法进行单元测试,以便测试可以运行得更快,并且实际上不需要等待20秒。使用moq框架。 感谢有关如何实现此目标的任何想法。

3 个答案:

答案 0 :(得分:1)

您实际上可以为Thread.sleep方法引入接口,并且可以在编写UT时进行模拟

 public interface IThreadSleep
{
    void Sleep(int milliSec);

}

您可以实现

 public class ThreadSleep : IThreadSleep
{
    public void Sleep(int milliSec)
    {
        Thread.Sleep(milliSec);
    }
}

在您的业务类中,只需注入此接口,然后您就可以模拟Thread.sleep

 public class Class1
{
    IThreadSleep _threadSleep;
    public Class1(IThreadSleep threadSleep)
    {
        _threadSleep = threadSleep;

    }

    public void SomeMethod()
    {
        // 
        _threadSleep.Sleep(100);
    }
}

希望这会有所帮助。

答案 1 :(得分:1)

可能没有办法模拟Thread.Sleep,因为它是静态方法,并且无法使用基于Moq的基于DynamicProxy的模拟框架进行模拟。

一种选择是使用基于Profiler API的工具,例如Microsoft Fakes(仅在VS Enterprise中)或Typemoq Professional。

更好的选择是不要在业务逻辑中直接调用Thread.Sleep。相反,您可以做的是引入这样的接口

public interface ISleepService
{
    void Sleep(int ms);
}

然后创建您在代码中使用的默认实现:

public class SleepService: ISleepService
{
    public void Sleep(int ms)
    {
       Thread.Sleep(ms);
    }
}

将ISleepService的依赖项添加到您的业务逻辑

public class MyBusinessLogic()
{
    private ISleepService _sleepService;
    public MyBusinessLogic(ISleepService sleepService)
    {
        _sleepService = sleepSerivce;
    }

    public void MyBusinessMethod()
    {
        // your code
        _sleeService.Sleep(20000);
        // more code
    }
}

然后您可以在单元测试中轻松模拟ISleepService并在生产代码中传递真实的实现

答案 2 :(得分:0)

不知道您拥有的实际代码,但至少有一些想法。您可以将Thread.Sleep包装到interface中,然后将其注入到业务处理程序\控制器中。在实际的实现中,使用Thread.Sleep来实际等待,但在测试中模拟interface来避免Thread.Sleep。例如:

public interface IMySleepContext
{
    void Sleep(int milliseconds);
}

public class MySleepContext : IMySleepContext
{
    public void Sleep(int milliseconds)
    {
        Thread.Sleep(milliseconds);
    }
}

public class MyController
{
    private readonly IMySleepContext _mySleepContext;

    public MyController(IMySleepContext mySleepContext)
    {
        _mySleepContext = mySleepContext;
    }

    public void MyMethod()
    {
        //do something
        _mySleepContext.Sleep(20000);
        //do somethign
    }
}

测试:

//Arrange
MyController mc = new MyController(Mock.Of<IMySleepContext>());

//Act
mc.MyMethod();

//Assert
//do assert