Testeando métodos asíncronos

Buenas,

He re-arrancado UniversalSync y lo he pasado todo a asíncrono utilizando async/await. Así he conseguido que las cosas vayan mucho más deprisa, pero han surgido nuevos problemas que voy abordando poco a poco.

Por ejemplo, ¿cómo testear la operación de PUT contra – por ejemplo – los contenedores de Blob, si es asíncrona?

    public class Synchronizer
    {

        public async Task<string> Put(string path, FileStream file)
        {
            var resultado = string.Empty;

            var albumOps = new AlbumOps(path);
            if (!albumOps.Exist())
            { resultado =  await albumOps.CreateAlbum(path); }

            var albumId = albumOps.AlbumEntity.RowKey;

            var repository = new Blob(new ConfigurationBlob());
            var blobOperations = new BlobOps(repository);
            var blobId = await blobOperations.Put(file);

            var fileOps = new FileOps(albumId, path, blobId);
            resultado = await fileOps.CreateFile();

            return resultado;
        }
}

Una aproximación para que funcione, es que lo haga de forma síncrona para el Test. Es decir, que haga todas las operaciones requeridas para que pueda obtener un resultado.

Y luego, recordar que lo me devuelve el método es un Task<string> que tiene un campo llamado Result, que es el que voy a utilizar para el Assert.

[TestMethod()]
public async void Synchronizer_Put()
        {
            var path = Path.GetFullPath(@"..\..\20160514_195832.jpg");
            var file = File.OpenRead(path);
            var sincronizador = new Synchronizer();

            var resultadoPut = sincronizador.Put(path, file);

            Assert.AreEqual("204", resultadoPut.Result, "Respuesta: " + resultadoPut.Result);
        }

Sin duda esta es una forma pedestre de probar, pero me viene al pelo para este estado del Test. Y siempre tengo tiempo para mejorarlo o complicarlo, como cuando vaya a abordar la lógica de negocio de reemplazos.

ACTUALIZACION: Googleando me he encontrado con una solución mucho más elegante y más potente, en donde el propio test lo hago asincrono, y utilizo await para esperar el resultado antes de lanzar el Assert.

[TestMethod()]
public async Task Synchronizer_Put()
        {
            var path = Path.GetFullPath(@"..\..\20160514_195832.jpg");
            var file = File.OpenRead(path);
            var sincronizador = new Synchronizer();

            var resultadoPut = await sincronizador.Put(path, file);

            Assert.AreEqual("204", resultadoPut, "Respuesta: " + resultadoPut);
        }

El truco, para que funcione y que aparezca en el listado de Test, es quitarle el void y declarar que va a retornar un a Task. Lo curioso es que no me pide ningún return; y he de reconocer que no sé porqué funciona…

Espero que te sea de ayuda

 

P.D. Feliz año 2017!!

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s