C# void异步方法的断言
我有一个类似的班级:C# void异步方法的断言,c#,testing,C#,Testing,我有一个类似的班级: public class MyClass { public Task MyMethod() { //do something } } 如前所述,“MyMethod”是异步的,为了简单起见,我们可以说这就是它的实现: public Task MyMethod() { return Task.Run(() => { var success = _someSer
public class MyClass
{
public Task MyMethod()
{
//do something
}
}
如前所述,“MyMethod”是异步的,为了简单起见,我们可以说这就是它的实现:
public Task MyMethod()
{
return Task.Run(() =>
{
var success = _someService.DoSomething();
if (!success) throw new Exception("unsuccsesfull");
});
}
显然,当MyMethod等待回调将运行时,这意味着在运行的线程中没有抛出异常,这意味着“MyMethod”调用成功
我想测试一下这个方法。测试方法如下所示:
[Test]
public async void TestMyMethod_TestInitialState_TestExpectedResult()
{
// test initialization..
//...
//..
var myClass = new MyClass();
await myClass.MyMethod();
Assert.That(????)
}
我的问题-正确的断言是什么
我有一个可能的解决方案-向“MyClass”添加一个逻辑成员,并根据方法结果更新此成员:
public class MyClass
{
public bool SomeMember { get; private set; }
public Task MyMethod()
{
Task.Run(() =>
{
SomeMember = _someService.DoSomething();
if (!SomeMember ) throw new Exception("unsuccsesfull");
});
}
}
这样,我可以像这样断言测试:
[Test]
public async void TestMyMethod_TestInitialState_SomeMemberShouldBeTrue()
{
// test initialization..
//...
//..
var myClass = new MyClass();
await myClass.MyMethod();
Assert.True(SomeMember)
}
}
但是,我不喜欢这个解决方案,因为我在“MyClass”中添加一个属性只是为了能够断言一个测试,在我的商业世界中我并不真正需要这个属性。此外,添加到类中的每个属性都表示该类的某些状态,并添加了一个comlexity级别
建议
伙计。你想要所谓的“模拟”或“存根”。其思想是重构代码,使其依赖于接口,然后在测试时模拟接口
有各种框架/工具可以帮助模拟(Moq、Microsoft Fakes、TypeMock Isolator、JustMock等),还有许多框架可以帮助解决与依赖注入密切相关的问题(Unity、Castle Windsor、StructureMap、Autofac等)
但你可以自己动手。首先,重构MyClass
,使其依赖于ISomeService
:
public interface ISomeService
{
bool DoSomething();
}
public class MyClass
{
private readonly ISomeService _someService;
public MyClass(ISomeService someService)
{
_someService = someService;
}
public Task MyMethod()
{
return Task.Run(() =>
{
var success = _someService.DoSomething();
if (!success) throw new Exception("unsuccsesfull");
});
}
}
然后在单元测试中:
private class TestService : ISomeService
{
public bool DoSomethingReturnValue { get; set; }
public bool DoSomething() { return DoSomethingReturnValue; }
}
[Test]
public async Task TestMyMethod_TestInitialState_TestExpectedResult()
{
var myClass = new MyClass(new TestService { DoSomethingReturnValue = true });
await myClass.MyMethod();
}
[Test]
public async Task TestMyMethod_TestInitialState_TestFailure()
{
var myClass = new MyClass(new TestService { DoSomethingReturnValue = false });
Assert.Throws(() => myClass.MyMethod()); // (I'm unsure of the exact NUnit syntax)
}
很可能异步操作会有一些效果,否则执行它就没有意义了。它在做什么,你能测试它发生了吗?在我的例子中,它向另一台计算机发送一个文件。这是通过交换通信消息和从另一台机器请求文件的TFTP服务器发送数据来完成的。我将通过从该机器收到的一条通信消息来了解该过程是否成功,该消息指示文件处于其会话中。我无法控制此通知消息何时到达,因此我正在使用异步接口。那么,在您的测试情况下,它会做什么?在这种情况下,可能它实际上并没有做TFTP…虽然我没有问过关于嘲笑的问题,但我认为你的回答符合我的要求。。谢谢