J'essaie de vérifier qu'une méthode asynchrone a été appelée avec les paramètres corrects. Cependant, je reçois l'avertissement:
"Parce que cet appel n'est pas attendu, l'exécution de la méthode actuelle se poursuit avant la fin de l'appel. Envisagez d'appliquer l'opérateur 'wait' au résultat de l'appel". Cet avertissement apparaît sur la ligne de code sous le commentaire //Assert
(Ci-dessous).
Mon test en utilisant NSubstitute est le suivant:
[Test]
public async Task SimpleTests()
{
//Arrange
var request = CreateUpdateItemRequest();
databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>()).Returns(Task.FromResult((object)null));
//Act
await underTest.ExecuteAsync(request);
//Assert
databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2"));
}
L'unité sous la méthode de test underTest.ExecuteAsync(request)
appelle ExecuteProcedureAsync
et effectue l'attente:
var ds = await DatabaseHelper.ExecuteProcAsync(dbParams);
En raison du fait qu'avec NSubstitute, le Received () est requis après l'exécution de l'unité testée. Alors que dans RhinoMocks, vous pouvez attendre pour qu'un appel se produise avant l'exécution de l'unité testée. RhinoMocks peut retourner le Task.FromResult () alors que NSubstitute ne le peut pas.
L'équivalent de RhinoMocks qui fonctionne est le suivant:
[Test]
public async Task SimpleTest()
{
// Arrange
var request = new UpdateItemRequest();
databaseHelperMock.Expect(m => m.ExecuteProcAsync(Arg<DatabaseParams>.Matches(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2
))).Return(Task.FromResult<object>(null));
// Act
await underTest.ExecuteAsync(request);
}
J'ai vu qu'il existe une solution de contournement où vous pouvez ajouter une méthode d'extension pour supprimer le problème:
public static class TestHelper
{
public static void IgnoreAwait(this Task task)
{
}
}
Cela signifie que ma ligne de test pour NSubstitute peut être exécutée comme suit et l'avertissement disparaît:
databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2")).IgnoreAwait();
}
Cependant, j'ai supposé qu'il devait y avoir une meilleure solution pour cela?
Dès que vous mettez à jour vers la version 1.9.0 ou supérieure, vous pourrez utiliser le await
sans recevoir un NullReferenceException
.
Chaque fois que le prédicat Received()
devient trop compliqué ou ne correspond tout simplement pas à NSubstitute, vous pouvez toujours capturer les arguments spécifiés en utilisant callbacks via When().Do()
ou .AndDoes()
. Pour votre cas d'utilisation qui irait quelque chose comme ça
DatabaseParams receivedParms = null;
databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>())
.Returns(Task.FromResult((object)null))
.AndDoes(x => receivedParms = x.Arg<DatabaseParams>);
//Act
await underTest.ExecuteAsync(request);
//Assert
receivedParms.Should().NotBeNull();
// assert your parms...
La réponse de Jake Ginnivan explique que l'attente reçue n'est pas requise, mais que le compilateur ne la comprend pas.
Vous pouvez supprimer l'avertissement en toute sécurité
#pragma warning disable 4014 //for .Received await is not required, so suppress warning “Consider applying the 'await' operator”
_service.Received(totalNumber).MyMethod(Arg.Any<ParamType>());
#pragma warning restore 4014