Condividi tramite


Unit Testing API Web ASP.NET 2

di Tom FitzMacken

Scaricare il progetto completato

Questa guida e applicazione illustra come creare unit test semplici per l'applicazione Api Web 2. Questa esercitazione illustra come includere un progetto di unit test nella soluzione e scrivere metodi di test che controllano i valori restituiti da un metodo controller.

Questa esercitazione presuppone che si abbia familiarità con i concetti di base di API Web ASP.NET. Per un'esercitazione introduttiva, vedere Introduzione con API Web ASP.NET 2.

Gli unit test in questo argomento sono intenzionalmente limitati a semplici scenari di dati. Per gli scenari di dati più avanzati, vedere Simulazione di Entity Framework quando Unit Testing API Web ASP.NET 2.

Versioni software usate nell'esercitazione

Contenuto dell'argomento

In questo argomento sono incluse le sezioni seguenti:

Prerequisiti

Visual Studio 2017 Community, Professional o Enterprise Edition

Scaricare il codice

Scaricare il progetto completato. Il progetto scaricabile include il codice unit test per questo argomento e per l'argomento Mocking Entity Framework quando unit testing API Web ASP.NET argomento.

Creare un'applicazione con il progetto di unit test

È possibile creare un progetto di unit test durante la creazione dell'applicazione o aggiungere un progetto di unit test a un'applicazione esistente. Questa esercitazione illustra entrambi i metodi per la creazione di un progetto di unit test. Per seguire questa esercitazione, è possibile usare entrambi gli approcci.

Aggiungere un progetto di unit test durante la creazione dell'applicazione

Creare una nuova applicazione Web ASP.NET denominata StoreApp.

creare un progetto

Nella finestra Nuovo ASP.NET Progetto selezionare il modello Vuoto e aggiungere cartelle e riferimenti di base per l'API Web. Selezionare l'opzione Aggiungi unit test . Il progetto di unit test viene denominato automaticamente StoreApp.Tests. È possibile mantenere questo nome.

creare un progetto di unit test

Dopo aver creato l'applicazione, verrà visualizzato contenente due progetti.

due progetti

Aggiungere un progetto di unit test a un'applicazione esistente

Se non è stato creato il progetto di unit test quando è stata creata l'applicazione, è possibile aggiungerlo in qualsiasi momento. Si supponga, ad esempio, di avere già un'applicazione denominata StoreApp e di aggiungere unit test. Per aggiungere un progetto di unit test, fare clic con il pulsante destro del mouse sulla soluzione e scegliere Aggiungi e Nuovo progetto.

aggiungere un nuovo progetto alla soluzione

Selezionare Test nel riquadro sinistro e selezionare Progetto unit test per il tipo di progetto. Assegnare un nome al progetto StoreApp.Tests.

aggiungere un progetto di unit test

Verrà visualizzato il progetto di unit test nella soluzione.

Nel progetto di unit test aggiungere un riferimento al progetto originale.

Configurare l'applicazione API Web 2

Nel progetto StoreApp aggiungere un file di classe alla cartella Modelsdenominata Product.cs. Sostituire il contenuto del file con il codice seguente.

using System;

namespace StoreApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

Compilare la soluzione.

Fare clic con il pulsante destro del mouse sulla cartella Controller e scegliere Aggiungi e Nuovo elemento Scaffolded. Selezionare Web API 2 Controller - Vuoto.

aggiungere un nuovo controller

Impostare il nome del controller su SimpleProductController e fare clic su Aggiungi.

specificare il controller

Sostituire il codice esistente con quello seguente. Per semplificare questo esempio, i dati vengono archiviati in un elenco anziché in un database. L'elenco definito in questa classe rappresenta i dati di produzione. Si noti che il controller include un costruttore che accetta come parametro un elenco di oggetti Product. Questo costruttore consente di passare i dati di test durante l'unit test. Il controller include anche due metodi asincroni per illustrare i metodi asincroni di unit test. Questi metodi asincroni sono stati implementati chiamando Task.FromResult per ridurre al minimo il codice extraneo, ma normalmente i metodi includono operazioni a elevato utilizzo di risorse.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using StoreApp.Models;

namespace StoreApp.Controllers
{
    public class SimpleProductController : ApiController
    {
        List<Product> products = new List<Product>();        
           
        public SimpleProductController() { }

        public SimpleProductController(List<Product> products)
        {
            this.products = products;
        }

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public async Task<IEnumerable<Product>> GetAllProductsAsync()
        {
            return await Task.FromResult(GetAllProducts());
        }

        public IHttpActionResult GetProduct(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }

        public async Task<IHttpActionResult> GetProductAsync(int id)
        {
            return await Task.FromResult(GetProduct(id));
        }
    }
}

Il metodo GetProduct restituisce un'istanza dell'interfaccia IHttpActionResult . IHttpActionResult è una delle nuove funzionalità dell'API Web 2 e semplifica lo sviluppo di unit test. Le classi che implementano l'interfaccia IHttpActionResult sono disponibili nello spazio dei nomi System.Web.Http.Results . Queste classi rappresentano le possibili risposte da una richiesta di azione e corrispondono ai codici di stato HTTP.

Compilare la soluzione.

È ora possibile configurare il progetto di test.

Installare pacchetti NuGet nel progetto di test

Quando si usa il modello Vuoto per creare un'applicazione, il progetto di unit test (StoreApp.Tests) non include pacchetti NuGet installati. Altri modelli, ad esempio il modello api Web, includono alcuni pacchetti NuGet nel progetto di unit test. Per questa esercitazione è necessario includere il pacchetto Microsoft API Web ASP.NET 2 Core al progetto di test.

Fare clic con il pulsante destro del mouse sul progetto StoreApp.Test e scegliere Gestisci pacchetti NuGet. È necessario selezionare il progetto StoreApp.Tests per aggiungere i pacchetti a tale progetto.

gestire i pacchetti

Trovare e installare il pacchetto Microsoft API Web ASP.NET 2 Core.

installare il pacchetto di base dell'API Web

Chiudere la finestra Gestisci pacchetti NuGet.

Creare test

Per impostazione predefinita, il progetto di test include un file di test vuoto denominato UnitTest1.cs. Questo file mostra gli attributi usati per creare metodi di test. Per gli unit test, è possibile usare questo file o creare un file personalizzato.

UnitTest1

Per questa esercitazione si creerà la propria classe di test. È possibile eliminare il file UnitTest1.cs. Aggiungere una classe denominata TestSimpleProductController.cs e sostituire il codice con il codice seguente.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Http.Results;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using StoreApp.Controllers;
using StoreApp.Models;

namespace StoreApp.Tests
{
    [TestClass]
    public class TestSimpleProductController
    {
        [TestMethod]
        public void GetAllProducts_ShouldReturnAllProducts()
        {
            var testProducts = GetTestProducts();
            var controller = new SimpleProductController(testProducts);

            var result = controller.GetAllProducts() as List<Product>;
            Assert.AreEqual(testProducts.Count, result.Count);
        }

        [TestMethod]
        public async Task GetAllProductsAsync_ShouldReturnAllProducts()
        {
            var testProducts = GetTestProducts();
            var controller = new SimpleProductController(testProducts);

            var result = await controller.GetAllProductsAsync() as List<Product>;
            Assert.AreEqual(testProducts.Count, result.Count);
        }

        [TestMethod]
        public void GetProduct_ShouldReturnCorrectProduct()
        {
            var testProducts = GetTestProducts();
            var controller = new SimpleProductController(testProducts);

            var result = controller.GetProduct(4) as OkNegotiatedContentResult<Product>;
            Assert.IsNotNull(result);
            Assert.AreEqual(testProducts[3].Name, result.Content.Name);
        }

        [TestMethod]
        public async Task GetProductAsync_ShouldReturnCorrectProduct()
        {
            var testProducts = GetTestProducts();
            var controller = new SimpleProductController(testProducts);

            var result = await controller.GetProductAsync(4) as OkNegotiatedContentResult<Product>;
            Assert.IsNotNull(result);
            Assert.AreEqual(testProducts[3].Name, result.Content.Name);
        }

        [TestMethod]
        public void GetProduct_ShouldNotFindProduct()
        {
            var controller = new SimpleProductController(GetTestProducts());

            var result = controller.GetProduct(999);
            Assert.IsInstanceOfType(result, typeof(NotFoundResult));
        }

        private List<Product> GetTestProducts()
        {
            var testProducts = new List<Product>();
            testProducts.Add(new Product { Id = 1, Name = "Demo1", Price = 1 });
            testProducts.Add(new Product { Id = 2, Name = "Demo2", Price = 3.75M });
            testProducts.Add(new Product { Id = 3, Name = "Demo3", Price = 16.99M });
            testProducts.Add(new Product { Id = 4, Name = "Demo4", Price = 11.00M });

            return testProducts;
        }
    }
}

Esecuzione dei test

È ora possibile eseguire i test. Tutti i metodi contrassegnati con l'attributo TestMethod verranno testati. Dalla voce di menu Test eseguire i test.

eseguire test

Aprire la finestra Esplora test e notare i risultati dei test.

risultati dei test

Riepilogo

L'esercitazione è stata completata. I dati in questa esercitazione sono stati intenzionalmente semplificati per concentrarsi sulle condizioni di unit test. Per gli scenari di dati più avanzati, vedere Mocking Entity Framework when Unit Testing API Web ASP.NET 2 (Simulazione di Entity Framework quando Unit Testing API Web ASP.NET 2).