# 12.4 Creando pruebas para el login

Vamos a crear una nueva clase para simular un servidor para nuestros servicios y vamos a mandar a llamar a nuestro servicio **Login** que es de tipo **Post**.

Agregamos una clase llamada Servicios donde incluiremos las llamadas a nuestros servicios.&#x20;

Utilizaremos un environment de testing, de esta forma en nuestro archivo Startup.cs de nuestro proyecto CaducaRest vamos a saber si el ambiente es de pruebas o de producción, si es de testing vamos a utilizar una base de datos en memoria, si no utilizaremos la de producción en este caso MySQL

También creamos un servidor de Pruebas, con la instrucción TestServer

Obtenemos nuestra base de datos y la inicializamos con valores por default.

{% tabs %}
{% tab title="Servicios.cs" %}

```csharp
public class Servicios
{
    private static HttpClient httpCliente;
    public static CaducaContext caducaContext;

    public static void Inicializa()
    {
        //Creamos un servidor de pruebas utilizando un ambiente
        //de testing
        var builder = new WebHostBuilder()
                .UseEnvironment("IntegrationTesting")
                .ConfigureAppConfiguration((c, config) =>
                {
                    config.SetBasePath(Path.Combine(
                        Directory.GetCurrentDirectory(),
                        "..", "..", "..", "..", "CaducaRest"));

                    config.AddJsonFile("appsettings.json");
                })
                .UseStartup<Startup>();
        //Esto nos crea un servidor con los servicios rest 
        var servidorPruebas = new TestServer(builder);
        //Obtenemos el objeto caducaContext
        caducaContext = servidorPruebas.Host.Services.GetService(typeof(CaducaContext)) as CaducaContext;
        //Inicializamos la bd con datos de prueba
        InicializaDatos.Inicializar(caducaContext);
        //var total =caducaContext.Usuario.Count();
        httpCliente = servidorPruebas.CreateClient();
    }

    public static async Task<bool> PostAsync(string servicio, 
                                             object datos)
    {
        var contenido = new StringContent(JsonConvert
                         .SerializeObject(datos), 
                             Encoding.UTF8, 
                             "application/json");
        var response = await httpCliente
                                  .PostAsync(servicio, contenido);
        if (response.StatusCode == HttpStatusCode.OK)
            return true;
        return false;
    }
}
```

{% endtab %}
{% endtabs %}

En specflow, los casos de prueba se crean en archivos llamados **Feature**. Agregamos un nuevo Feature, damos clic con el botón derecho del mouse y damos clic en Agregar , seleccionamos **SpecFlow** y luego **SpecFlow Feature File**, tecleamos **Login.feature**

![](https://3731331968-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LKmGSg4qhizjqeDPHJC%2F-Lso6Ph499u5VlyxG-3e%2F-LsoAF-OPv4lUdhRnJXh%2Fimage.png?alt=media\&token=50f25d34-da94-4213-9d9a-bbf4f6dcf5f1)

Nos crea un ejemplo para sumar 2 números

En Feature ponemos las precondiciones de nuestra prueba. En mi caso por simplicidad utilizaré los mismos usuarios y passwords que creamos.

{% tabs %}
{% tab title="Login.feature" %}

```gherkin
Feature: Login	Dado que ya existen los siguientes usuarios:	
Usuario  Nombre
Carlos   Carlos Hernández 
Maria    Maria Lopez
Juan     Juan Peréz
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Puedes crear usuario de prueba en tu archivo InicializaDatos para probar con usuarios ficticios.
{% endhint %}

En specflow utilizamos escenarios para probar los diferentes casos de prueba. Agregamos un  **Scenario**&#x20;

```gherkin
@Login
Scenario: Login con usuario 
Given Que Existe un usuario con la clave Carlos			
When Yo ejecuto el servicio Usuarios/Login 	
Then Obtengo el nombre Carlos Hernández
```

Se muestran el color morado porque no hemos escrito el código para cada paso, para esto da clic con el botón derecho del mouse y da  clic en **Generate Step Definitinions**

Esto nos creará los pasos faltantes de código, seleccionamos **Generate** para que nos cree los pasos en una clase nueva.

Seleccionamos la ruta donde deseamos que nos cree la clase

![](https://3731331968-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LKmGSg4qhizjqeDPHJC%2F-Lso6Ph499u5VlyxG-3e%2F-LsoBjlEWha0CwNO1F2E%2Fimage.png?alt=media\&token=8ae22017-7f6d-4f34-a82d-5763e08e9af9)

Nos crea una clase con cada uno de los pasos de nuestro escenario.

Podemos indicar que ciertos textos son parámetros sustituyendo el texto por (.\*) y agregando una variable por cada valor que deseamos sustituir

Tecleamos el código para probar el login.

{% tabs %}
{% tab title="LoginSteps.cs" %}

```csharp
[Binding]
public class LoginSteps
{
    private LoginDTO login = new LoginDTO();
    private TokenDTO token = new TokenDTO();

    [Given(@"Que Existe un usuario con la clave (.*)")]
    public void GivenQueExisteUnUsarioConLaClave(string usuario)
    {
        login.Usuario = usuario;
        login.Password = "DtfhkmTRQ8mNzgRY";
    }
    
    [When(@"Yo ejecuto el servicio (.*)")]
    public async Task WhenYoEjecutoElServicioAsync(string nombreServicio)
    {
        Servicios.Inicializa();
        var response = await Servicios.PostAsync(nombreServicio, login);
        if (!string.IsNullOrEmpty(response))
            token = JsonSerializer.Deserialize<TokenDTO>(response);
    }

    [Then(@"Obtengo el nombre (.*)")]
    public void ThenObtengoElNombre(string nombreUsuario)
    {
        Assert.AreEqual(nombreUsuario, token.Nombre, "El nombre del usuario no coincide");
    }
}
```

{% endtab %}
{% endtabs %}

Compilamos la solución para que se nos agregue al panel de Pruebas

De esta forma nuestras pruebas de integración nos pueden servir como documentación

Puedes ver la documentación aquí.

{% embed url="<https://specflow.org/getting-started/>" %}

En nuestro proyecto CaducaRest cambiamos en la clase **Startup.cs** el método **ConfigureServices** la configuración de swagger para leer los comentarios xml, ya que toma en cuenta la ruta de la dll del proyecto CaducaRest y estamos simulando un servidor, no tenemos acceso a los comentarios xml agregamos un if para excluir esa parte si el assembly es TestHost el cual es el servidor de pruebas que creamos.

También cambiamos la configuración de la base de datos, para indicar que si el **environment** es **Testing** se utilice la base de datos en memoria.

{% tabs %}
{% tab title="Startup.cs" %}

```csharp
public void ConfigureServices(IServiceCollection services)
{
    if (CurrentEnvironment.IsEnvironment("Testing"))
    {
        //Conexión en Memoria
        services.AddDbContext<CaducaContext>(opt =>
                                   opt.UseInMemoryDatabase("Caltic")
                                   .ConfigureWarnings
                                   (x => x.Ignore(
                                   InMemoryEventId
                                        .TransactionIgnoredWarning)));
     }
     else
     {
        //Conexión MySQL
        services.AddDbContext<CaducaContext>(
            options => options.UseMySql(Configuration
                    .GetConnectionString("DefaultConnection")));
    } 
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "Api Caduca REST", 
               Version = "v1" });
        //Obtenemos el nombre de la dll por medio de reflexión
        var assemblyName = System.Reflection.Assembly
                      .GetEntryAssembly().GetName().Name;
        if (assemblyName != "testhost")
        {
            //Obtenemos el directorio actual
            var basePath = AppContext.BaseDirectory;
            //Demás código
```

{% endtab %}
{% endtabs %}

Puedes correr las pruebas en Visual Studio y ver si cumple o no con el caso que estas probando.

{% hint style="warning" %}
Mas adelante se incluirá una sección para no almacenar los password en código.
{% endhint %}
