Moq & C #: callback no válida. La configuración en el método con parámetros no puede invocar la callback con parámetros

La firma de la interfaz real es la siguiente

Task UpdateAsync(ICustomerRequest<IEnumerable> request, CancellationToken cancellationToken, ILoggingContext loggingContext = null); 

Caso de prueba:

 ICustomerRequest<IEnumerable> t = null; CancellationToken t1 = new CancellationToken(); LoggingContext t2 = null; this.customerPreferenceRepositoryMock.Setup(x => x.UpdateAsync( It.IsAny<ICustomerRequest<IEnumerable>>(), It.IsAny(), It.IsAny())) .Callback<ICustomerRequest<IEnumerable>,CancellationToken, LoggingContext>((a, b, c) => { t = a ; t1 =b;t2= c; }); 

La configuración está lanzando una excepción en el testcase, como se muestra abajo

Devolución de llamada no válida. La configuración en el método con parámetros (ICustomerRequest 1,CancellationToken,ILoggingContext) cannot invoke callback with parameters (ICustomerRequest 1, Cancelación de llamada, LoggingContext).

¿Qué es lo que estoy haciendo mal?

He verificado Moq: callback no válida. La configuración en el método con parámetros no puede invocar la callback con parámetros

Pero no vi ninguna ayuda.

Como se mencionó en los comentarios, los parámetros de Callback utilizados no coinciden con la definición del método. A pesar de que la Setup usa It.IsAny la definición del método usa el parámetro ILoggingContext

Cambiar t2 a

 ILoggingContext t2 = null; 

Y actualizar la Callback de Callback a

 .Callback>,CancellationToken, ILoggingContext>((a, b, c) => { t = a; t1 = b; t2 = c; }); 

o

 .Callback((ICustomerRequest> a, CancellationToken b, ILoggingContext c) => { t = a; t1 = b; t2 = c; }); 

De cualquier manera funcionará.

También recomendaría que la Setup devuelva una Task completada para permitir que la prueba fluya de forma asíncrona como se esperaba.

 this.customerPreferenceRepositoryMock .Setup(x => x.UpdateAsync( It.IsAny>>(), It.IsAny(), It.IsAny())) .Callback((ICustomerRequest> a, CancellationToken b, ILoggingContext c) => { t = a; t1 = b; t2 = c; //Use the input to create a response //and pass it to the `ReturnsAsync` method }) .ReturnsAsync(new GeneralResponseType()); //Or some pre initialized derivative. 

Revise el Inicio rápido de Moq para comprender mejor cómo usar el marco.