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 раз.
Как я понимаю, утверждение происходит до того, как значение было поставлено в очередь другим потоком, но как такое поведение можно протестировать?
Windows тесты поддерживают async/ждут, по крайней мере, в текущих версиях визуальной студии. Просто ждите таких методов, как в обычном коде. сделайте свой тестовый метод «public async Task Send_ValidMessage_ExecuteWriteMethodWithGivenValue()», а затем вызовите '.Wait()' вызовы 'await'. –