public class Composer
{
private Task _ComposerTask;
private ConcurrentQueue<IValue> _Values;
public bool IsConnected { get; }
// Other dependencies
private IClient _Client;
private IWriter _Writer
public Task async ConnectAsync()
{
this.IsConnected = await _Client.ConnectAsync();
_ComposerTask = Task.Run(() => this.Start());
}
private void Start()
{
while(this.IsConnected)
{
IValue value;
if(_Values.TryDequeue(out value) == false)
continue;
_Writer.Write(value);
}
}
public void Send(IValue value)
{
_Values.Enqueue(value);
}
}
當連接成功Composer
類執行Start
方法異步(在另一個線程)。
Start
方法檢查值的隊列並在值存在時將其發送。單元測試方法在另一個線程上
我在測試Send
方法時遇到問題。
[Test]
public void Send_ValidMessage_ExecuteWriteMethodWithGivenValue()
{
// Arrange
var fakeValue = Mock.Create<IValue>();
var fakeWriter = Mock.Create<IWriter>();
var fakeClient = Mock.Create<IClient>();
Mock.Arrange(() => fakeClient.ConnectAsync().Returns(CompletedTask);
var composer = new Composer(fakeClient, fakeWriter);
// for (int i = 0; i < 10; i++)
// {
// composer.Send(Mock.Create<IValue>());
// }
composer.ConnectAsync().Wait();
// Act
composer.Send(fakeValue);
// Assert
Mock.Assert(() => fakeWriter.Write(fakeValue), Occurs.Once());
}
帶註釋for loop
測試通過。但是如果執行for loop
並且內部隊列將在預期值添加之前填充10個值,則測試失敗,並且預期消息:至少一次,但發生0次。
據我所知,斷言發生在值由另一個線程排隊之前,但是如何測試這種行爲?
至少在當前版本的Visual Studio中,Windows測試支持異步/等待。只需等待你在普通代碼中的方法。使你的測試方法做'公共異步任務Send_ValidMessage_ExecuteWriteMethodWithGivenValue()',然後把'.Wait()'調用到'await'。 –