假设我有一个像这样的简单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
}
}
但是当我调试任务只是在短线上等待X秒(在甚至调用api.GetSomething()之前)时,这并没有按预期工作
如何调整这些测试以获得所需的行为?
作为一个额外的奖励,如果有可能不必等待休息时间,那就太棒了。
答案 0 :(得分:0)
您可以使用“Assert.Throws”nunit断言测试异常。您可以使用秒表测试在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秒或类似的情况。
答案 1 :(得分:0)
对于快乐的道路,请尝试
Assert.That(() => api.GetSomething(), Is.EqualTo(expected).After(3).Seconds));
您可能需要调整时间,因为它会受到延迟的影响。
对于失败,你需要在api中注入模拟或假冒,这需要太长时间然后......
Assert.That(() => api.GetSomething(), Throws.Typeof<MyException>());
这是所有论坛代码,因此请注意错误。 : - )