【发布时间】:2016-11-04 18:04:20
【问题描述】:
考虑代码:
class TestClass
{
private bool _someFlag;
private object _sharedObject = new object();
private readonly object _syncObject = new object();
public object Read()
{
//lock (_syncObject)
{
_someFlag = false;
return _sharedObject;
}
}
public void Write(object obj)
{
//lock (_syncObject)
{
_someFlag = true;
_sharedObject = obj;
}
}
}
它有竞争条件问题。当我们调用Read() 时,某些线程可以在_someFlag = false; 和return _sharedObject; 行之间调用Write()。我将通过lock 运营商解决问题。但是你能帮我对这个竞争条件问题进行单元测试吗?
我不想将 _someFlag 更改为 public 以进行测试或类似的事情。
我想做这样的事情:
[Fact]
public void RaceConditionTest()
{
var correctObject = new object();
var test = new TestClass();
for (int i = 0; i < 1000; i++)
{
test.Write(correctObject);
var assertTask = Task.Run(() =>
{
var actualObj = test.Read();
Assert.True(object.ReferenceEquals(correctObject, actualObj), $"Failed on {i} iteration");
});
//Thread.Sleep(50);
var failTask = Task.Run(() => test.Write(new object()));
Task.WaitAll(assertTask, failTask);
}
}
但是我怎么能确定assertTask 会在failTask 之前启动呢?或者也许还有另一种方法可以对这种情况进行单元测试?提前致谢。
【问题讨论】:
-
竞争条件可能无法进行单元测试,无论是正面还是尤其是负面。为了使代码可靠地执行您不想要的操作,您必须专门设置同步机制,强制操作以可靠的顺序发生,以便您可以可靠地重现不良行为。但是要添加同步以可靠地产生不良行为,您现在强制代码行为错误;您可以轻松地编写它以使其行为正确,如果您不确定是否有,则不能依赖测试。
标签: c# multithreading unit-testing thread-safety race-condition