test method await async c# .net asynchronous async-await moq

await - async test method c#



Moq con la tarea aguarda (3)

Desde que convertí mis métodos WCF a Async, mis pruebas de unidad han fallado, y no puedo entender la sintaxis correcta para que funcionen.

Clase de proxy Cllient

public interface IClientProxy { Task DoSomething(CredentialDataList credentialData, string store); }

clase de servicio

public class CredentialSync : ICredentialSync { private ICredentialRepository _repository; private IClientProxy _client; public CredentialSync() { this._repository = new CredentialRepository(); this._client = new ClientProxy(); } public CredentialSync(ICredentialRepository repository, IClientProxy client) { this._repository = repository; this._client = client; } public async Task Synchronise(string payrollNumber) { try { if (string.IsNullOrEmpty(payrollNumber)) { .... some code } else { CredentialDataList credentialData = new CredentialDataList(); List<CredentialData> credentialList = new List<CredentialData>(); // fetch the record from the database List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber); var pinData = this._repository.GetCredentialPinData(payrollNumber); // get the stores for this employee var storeList = data.Where(a => a.StoreNumber != null) .GroupBy(a => a.StoreNumber) .Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray(); var credential = this.ExtractCredentialData(data, pinData, payrollNumber); credentialList.Add(credential); credentialData.CredentialList = credentialList; foreach (var store in storeList) { //this line causes an Object reference not set to an instance of an object error await _client.DoSomething(credentialData, store.StoreNumber); } } } catch (Exception ex) { throw new FaultException<Exception>(ex); } }

Clase de prueba

/// </summary> [TestClass] public class SynchTest { private Mock<ICredentialRepository> _mockRepository; private Mock<IClientProxy> _mockService; [TestInitialize] public void Setup() { ... some setups for repository which work fine } [TestMethod] public async Task SynchroniseData_WithOneEmployee_CallsReplicateService() { this._mockService = new Mock<IClientProxy>(); this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>())); // arrange string payrollNumber = "1"; CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object); // act await service.Synchronise(payrollNumber); // assert this._mockService.VerifyAll(); }

El error es cuando se llama ClientProxy.DoSomething :

Referencia a objeto no establecida como instancia de un objeto

Los parámetros son buenos

Si convierto mi método ClientProxy.DoSomething a un método síncrono (public void DoSomething(...) ) el código funciona bien, pero necesito que esto se llame de forma asíncrona.


Creo que debes devolver la Task desde el simulacro DoSomething

this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>())) .Returns(Task.FromResult<int>(0));


Puede reducir la cantidad de desorden en el código usando ReturnsAsync

this._mockService.Setup(...).ReturnsAsync(false) ;

De esta forma puede eliminar la parte Task.FromResult del código


DoSomething devuelve null lugar de devolver una Task , por lo que obtienes una excepción cuando lo esperas. Debe especificar al construir el simulacro que debe devolver una Task .

En este caso, parece que simplemente puede devolver una tarea ya completada usando Task.FromResult para que la configuración simulada se vea así:

this._mockService.Setup(...).Returns(Task.FromResult(false));

A partir de la próxima versión de .Net (4.6) puede usar Task.CompletedTask