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);
}
}
Lorsque vous êtes connecté classe Composer
avec succès méthode d'exécution Start
de manière asynchrone (sur un autre thread).
Start
méthode vérifie la file d'attente des valeurs et l'envoie vers l'avant si la valeur existe.méthodes de tests unitaires sur un autre thread
Mon problème lors du test d'une méthode 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());
}
Avec commenté for loop
test réussi. Mais si for loop
exécuté et la file d'attente interne sera rempli avec même 10 valeurs avant la valeur ajoutée attendue, le test échoue avec le message: attendu au moins une fois, mais se produit 0 fois. Comme je comprends l'assertion se produit avant que la valeur a été mise en file d'attente par un autre thread, mais comment ce type de comportement peut-il être testé?
Windows tests support async/await, au moins dans les versions actuelles de Visual Studio. Attendez juste les méthodes comme vous le feriez dans le code normal. faites en sorte que votre méthode de test fasse 'public async Task Send_ValidMessage_ExecuteWriteMethodWithGivenValue()' puis placez vos appels '.Wait()' dans 'await'. –