C#-X秒后断言组件超时的测试

C#-X秒后断言组件超时的测试,c#,nunit,rhino-mocks,C#,Nunit,Rhino Mocks,假设我有这样一个简单的Api类,其中进行了一个外部调用,但如果未完成,则在5秒后抛出一个异常: public class Api { private readonly IConnector connector; public Api(IConnector connector) { this.connector = connector; } public string GetSomething() { var ti

假设我有这样一个简单的Api类,其中进行了一个外部调用,但如果未完成,则在5秒后抛出一个异常:

public class Api
{
    private readonly IConnector connector;

    public Api(IConnector connector)
    {
        this.connector = connector;
    }

    public string GetSomething()
    {
        var timer = new System.Timers.Timer(5000);
        timer.Elapsed += TimeOut;

        timer.Start();
        //some external call which takes time
        connector.Retrieve();
        timer.Stop();

        return "Something";
    }

    private void TimeOut(object sender, ElapsedEventArgs e)
    {
        throw new TimeoutException("Timed out!");
    }
}
使用NUnit或其他方法,我如何测试当请求耗时8秒时,上面的异常是否会抛出,但当请求耗时3秒时,异常是否会成功

我尝试了以下方法:

[TestFixture]
public class ApiTests
{
    IConnector mockConnector;
    Api api;

    [SetUp]
    public void Setup()
    {
        mockConnector = MockRepository.GenerateMock<IConnector>();
        api = new Api(mockConnector);
    }

    [Test]
    public void Api_RetrieveTakes3Seconds_SomethingReturned()
    {
        mockConnector.Stub(c => c.Retrieve()).Return(Task.Delay(3000).ContinueWith(c => "Something").Result);
        var response = api.GetSomething();

        Assert.AreEqual("Something", response);
    }

    [Test]
    public void Api_RetrieveTakes8Seconds_TimeOutExceptionThrown()
    {
        mockConnector.Stub(c => c.Retrieve()).Return(Task.Delay(8000).ContinueWith(c => "Something").Result);
        var response = api.GetSomething();

        //assert an exception is thrown on the above
    }

}
[TestFixture]
公开考试
{
i连接器;
Api;
[设置]
公共作废设置()
{
mockConnector=MockRepository.GenerateMock();
api=新api(模拟连接器);
}
[测试]
public void Api_retrieveTakes3s_SomethingReturned()
{
mockConnector.Stub(c=>c.Retrieve()).Return(Task.Delay(3000).ContinueWith(c=>Something”).Result);
var response=api.GetSomething();
断言。相等(“某物”,回应);
}
[测试]
public void Api_RetrieveTakes8Seconds_timeoutException抛出()
{
mockConnector.Stub(c=>c.Retrieve()).Return(Task.Delay(8000).ContinueWith(c=>Something”).Result);
var response=api.GetSomething();
//断言在上面的服务器上引发异常
}
}
但这并不像预期的那样有效,当我调试任务时,任务只是在存根行上等待X秒(甚至在调用api.GetSomething()之前)

如何调整这些测试以获得所需的行为


作为额外的好处,如果可以不必等待REST运行,那就太好了。

您可以使用“Assert.Throws”nunit Assert测试异常。您可以使用如下秒表测试在x个时间段后返回值:

[Test]
    public void Api_RetrieveTakes3Seconds_SomethingReturned()
    {
        mockConnector.Stub(c => c.Retrieve()).Return(Task.Delay(3000).ContinueWith(c => "Something").Result);
        topwatch sw = new Stopwatch();
        sw.Start();
        var response = api.GetSomething();
        sw.Stop();
        Assert.That(sw.ElapsedMilliseconds, Is.LessThanOrEqualTo(3000));        }

    [Test]
    public void Api_RetrieveTakes8Seconds_TimeOutExceptionThrown()
    {
        mockConnector.Stub(c => c.Retrieve()).Return(Task.Delay(8000).ContinueWith(c => "Something").Result);

        Assert.Throws(Exception, ()=> api.GetSomething());
    }

您需要添加一点缓冲区,因为您的测试正等待3秒,所以您可能应该检查测试是否在3.1秒或类似的时间内返回

要想找到快乐之路,试试看

Assert.That(() => api.GetSomething(), Is.EqualTo(expected).After(3).Seconds));
您可能需要调整时间,因为它会受到延迟的影响

对于失败,您需要在api中注入模拟或伪代码,这需要花费太长的时间,然后

Assert.That(() => api.GetSomething(), Throws.Typeof<MyException>());
Assert.That(()=>api.GetSomething(),Throws.Typeof());

这是所有论坛代码,请注意错误。:-)

也许可以尝试“mockConnector.Stub(c=>c.Retrieve())。Return(()=>Task.Delay(3000)。ContinueWith(c=>“Something”).Result);”让您的代码在正确的线路上等待?嗯,但这似乎遇到了同样的问题,在Stub上调用Retrieve()时不会出现人为延迟-它只是在创建Stub时发生。Retrieve()调用仍然是即时的。谢谢,但是它会使Retrieve()的模拟存根花费太长时间,这就是问题所在。这是怎么做到的?不是犀牛,但我想其他一些答案告诉你怎么做。