C# 如何使用NUnit通过异步单元测试测试竞争条件?
这是我要测试的赛车状态代码, 我有一个可以在一定程度上更改的遗留代码。 在我的主函数中,有一个函数返回我们等待的任务,还有一个函数用于UI,它不能被阻止,因为它运行在不同的线程上 在原始代码中,我们不关心结果,我们只是初始化一些类,我测试ViewModel是否为null 在我这里给出的示例代码中,我修改了代码以举例说明竞争条件的问题。 目前,我的测试将失败如何正确测试我的赛车状态C# 如何使用NUnit通过异步单元测试测试竞争条件?,c#,multithreading,unit-testing,C#,Multithreading,Unit Testing,这是我要测试的赛车状态代码, 我有一个可以在一定程度上更改的遗留代码。 在我的主函数中,有一个函数返回我们等待的任务,还有一个函数用于UI,它不能被阻止,因为它运行在不同的线程上 在原始代码中,我们不关心结果,我们只是初始化一些类,我测试ViewModel是否为null 在我这里给出的示例代码中,我修改了代码以举例说明竞争条件的问题。 目前,我的测试将失败如何正确测试我的赛车状态 [TestClass] public class UnitTest1 { [Tes
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Myclass tempClass = new Myclass();
tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
}
public class Myclass
{
public int Sum;
public Myclass()
{
Sum = 0;
}
public async Task CreateImage()
{
await InternalFunction();
await Task.Run(() => Physics());
}
public async Task InternalFunction()
{
await Task.Run(() =>
{
Math();
});
}
public void Math()
{
Sum += 1;
}
public void Physics()
{
Sum += 2;
}
}
如果我运行测试,sum属性将是1,而不是预期的3。如何更改代码以执行
CreateImage()
函数的所有流程,并且仅在所有线程完成后,我希望断言TempClass的结果/内容。CreateImage方法是异步的,但是您的单元测试方法不是,因此您的测试可以在CreateImage完成之前完成
您没有指定正在使用哪个版本的NUnit,但以下内容适用于最新版本的NUnit 3
[TestFixture]
public class UnitTest1
{
[Test]
public async Task TestMethod1()
{
Myclass tempClass = new Myclass();
await tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
}
当然,这假设<代码> MyClass <代码>是线程安全的-如果您的实际代码使用多个线程同时修改<代码> MyClass 实例的状态,那么您也可能需要考虑使用同步机制,如BCL—
中所构建的同步机制。此外,您可以考虑使用Stephen Cleary开发的一些异步友好的帮助器-
,您也必须在测试本身中等待代码,否则AsieT将在代码完成之前发生: [TestMethod]
public async Task TestMethod1()
{
Myclass tempClass = new Myclass();
await tempClass.CreateImage();
Assert.AreEqual(3, tempClass.Sum);
}
但对我来说,这个代码有一些缺点。
任务中有很多包装同步代码。运行
不会像现在这样带来任何好处。另外,Sum
不是线程安全的,因此,如果在任何时间点它将被线程访问,则可能会发生并发的错误 不清楚你在问什么。为什么不在单元测试中等待CreateImage()
调用呢?这样,在所有操作完成之前,您不会执行断言。你到底有什么问题?你试过什么?“为什么不起作用?”彼得杜尼奥感谢我编辑问题的反馈。