我的集成测试如下所示:
[TestMethod]
public async Task TestMethod1()
{
Guid guid = Guid.NewGuid();
using (HttpClient client = new HttpClient())
await client.GetAsync(String.Format(_uri, guid.ToString()));
Guid retrieved = GetLastGuid();
Assert.AreEqual(guid, retrieved);
}
client.GetAsync
正在呼叫一个简单的Web服务,它将Guid保存在数据库表中。 GetLastGuid
对表执行以下查询:
select top 1 * from dbo.Messages order by MessageId desc
其中message id是消息表上的标识列。
将试图测试数据库交互的智慧放在一边,我看到以下行为,从纯粹的技术角度来看,我很想知道发生了什么。
我期待发生什么
该服务已被调用,Guid将保存到数据库中。查找数据库表中的最新行将返回最后一个条目。我的理解(以及我怀疑我不正确的地方)是在SQL服务器上执行存储过程是一个同步过程,即它在提交事务之前不会返回。
实际发生的事情
将几次调用链接到我的测试方法会导致其中一些失败。看起来他们正在为之前的电话检索Guid。
我认为可能是原因
我怀疑我假设存储过程调用是同步的,并且我的失败测试实际上是在上一次事务提交之前尝试读取最新值。唯一让我怀疑的是,将GetLastGuid
查询设置为未提交读取仍会导致同样的问题。
所有测试方法都按顺序运行,没有其他内容写入此数据库表。明智地使用Thread.Sleep /在调试模式下运行可以解决问题,这是竞争条件的所有经典迹象。
答案 0 :(得分:1)
select top 1并不保证能为您提供正确的guid。您应该指定从dbo.Messages中选择*,其中guid = @guid或者从http客户端调用返回messageid(?)并使用它来获取数据并比较guid。虽然如果没有返回数据应该是第一个要检查的断言。