단위 테스트 ASP.NET Web API 2

Tom FitzMacken

완료된 프로젝트 다운로드

이 지침 및 애플리케이션은 Web API 2 애플리케이션에 대한 간단한 단위 테스트를 만드는 방법을 보여 줍니다. 이 자습서에서는 솔루션에 단위 테스트 프로젝트를 포함하고 컨트롤러 메서드에서 반환된 값을 검사 테스트 메서드를 작성하는 방법을 보여 줍니다.

이 자습서에서는 ASP.NET Web API 기본 개념을 잘 알고 있다고 가정합니다. 소개 자습서는 ASP.NET Web API 2를 사용한 시작 참조하세요.

이 항목의 단위 테스트는 의도적으로 간단한 데이터 시나리오로 제한됩니다. 더 많은 고급 데이터 시나리오를 단위 테스트하려면 단위 테스트 시 Entity Framework 모의 ASP.NET Web API 2를 참조하세요.

자습서에서 사용되는 소프트웨어 버전

항목 내용

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

사전 요구 사항

Visual Studio 2017 Community, Professional 또는 Enterprise Edition

코드 다운로드

완료된 프로젝트를 다운로드합니다. 다운로드 가능한 프로젝트에는 이 항목에 대한 단위 테스트 코드와 Unit Testing이 ASP.NET Web API 때 모의 엔터티 프레임워크에 대한 단위 테스트 코드가 포함되어 있습니다.

단위 테스트 프로젝트를 사용하여 애플리케이션 만들기

애플리케이션을 만들 때 단위 테스트 프로젝트를 만들거나 기존 애플리케이션에 단위 테스트 프로젝트를 추가할 수 있습니다. 이 자습서에서는 단위 테스트 프로젝트를 만들기 위한 두 가지 방법을 모두 보여 줍니다. 이 자습서를 따르려면 두 방법 중 하나를 사용할 수 있습니다.

애플리케이션을 만들 때 단위 테스트 프로젝트 추가

StoreApp이라는 새 ASP.NET 웹 애플리케이션을 만듭니다.

프로젝트 만들기

새 ASP.NET 프로젝트 창에서 템플릿을 선택하고 Web API에 대한 폴더 및 핵심 참조를 추가합니다. 단위 테스트 추가 옵션을 선택합니다. 단위 테스트 프로젝트의 이름은 자동으로 StoreApp.Tests입니다. 이 이름을 유지할 수 있습니다.

단위 테스트 프로젝트 만들기

애플리케이션을 만든 후 두 개의 프로젝트가 포함된 것을 볼 수 있습니다.

두 개의 프로젝트

기존 애플리케이션에 단위 테스트 프로젝트 추가

애플리케이션을 만들 때 단위 테스트 프로젝트를 만들지 않은 경우 언제든지 추가할 수 있습니다. 예를 들어 StoreApp이라는 애플리케이션이 이미 있고 단위 테스트를 추가하려는 경우를 가정해 보겠습니다. 단위 테스트 프로젝트를 추가하려면 솔루션을 마우스 오른쪽 단추로 클릭하고 추가새 프로젝트를 선택합니다.

솔루션에 새 프로젝트 추가

왼쪽 창에서 테스트를 선택하고 프로젝트 유형에 대한 단위 테스트 프로젝트를 선택합니다. 프로젝트 이름을 StoreApp.Tests로 지정합니다.

단위 테스트 프로젝트 추가

솔루션에 단위 테스트 프로젝트가 표시됩니다.

단위 테스트 프로젝트에서 원래 프로젝트에 프로젝트 참조를 추가합니다.

Web API 2 애플리케이션 설정

StoreApp 프로젝트에서 Product.cs라는 Models 폴더에 클래스 파일을 추가합니다. 파일 내용을 다음 코드로 바꿉니다.

using System;

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

솔루션을 빌드합니다.

Controllers 폴더를 마우스 오른쪽 단추로 클릭하고 추가새 스캐폴드된 항목을 선택합니다. Web API 2 컨트롤러 - 비어 있음을 선택합니다.

새 컨트롤러 추가

컨트롤러 이름을 SimpleProductController로 설정하고 추가를 클릭합니다.

컨트롤러 지정

기존 코드를 다음 코드로 바꿉니다. 이 예제를 간소화하기 위해 데이터는 데이터베이스가 아닌 목록에 저장됩니다. 이 클래스에 정의된 목록은 프로덕션 데이터를 나타냅니다. 컨트롤러에는 Product 개체 목록의 매개 변수로 사용하는 생성자가 포함됩니다. 이 생성자를 사용하면 단위 테스트 시 테스트 데이터를 전달할 수 있습니다. 컨트롤러에는 단위 테스트 비동 메서드를 설명하는 두 개의 비동기 메서드도 포함되어 있습니다. 이러한 비동기 메서드는 불필요한 코드를 최소화하기 위해 Task.FromResult 를 호출하여 구현되었지만 일반적으로 메서드에는 리소스를 많이 사용하는 작업이 포함됩니다.

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));
        }
    }
}

GetProduct 메서드는 IHttpActionResult 인터페이스의 instance 반환합니다. IHttpActionResult는 Web API 2의 새로운 기능 중 하나이며 단위 테스트 개발을 간소화합니다. IHttpActionResult 인터페이스를 구현하는 클래스는 System.Web.Http.Results 네임스페이스에 있습니다. 이러한 클래스는 작업 요청에서 가능한 응답을 나타내며 HTTP 상태 코드에 해당합니다.

솔루션을 빌드합니다.

이제 테스트 프로젝트를 설정할 준비가 되었습니다.

테스트 프로젝트에 NuGet 패키지 설치

빈 템플릿을 사용하여 애플리케이션을 만드는 경우 단위 테스트 프로젝트(StoreApp.Tests)에는 설치된 NuGet 패키지가 포함되지 않습니다. Web API 템플릿과 같은 다른 템플릿에는 단위 테스트 프로젝트에 일부 NuGet 패키지가 포함됩니다. 이 자습서에서는 테스트 프로젝트에 Microsoft ASP.NET Web API 2 Core 패키지를 포함해야 합니다.

StoreApp.Tests 프로젝트를 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리를 선택합니다. 해당 프로젝트에 패키지를 추가하려면 StoreApp.Tests 프로젝트를 선택해야 합니다.

패키지 관리

Microsoft ASP.NET Web API 2 Core 패키지를 찾아 설치합니다.

Web api Core 패키지 설치

NuGet 패키지 관리 창을 닫습니다.

테스트 만들기

기본적으로 테스트 프로젝트에는 UnitTest1.cs라는 빈 테스트 파일이 포함됩니다. 이 파일은 테스트 메서드를 만드는 데 사용하는 특성을 보여 줍니다. 단위 테스트의 경우 이 파일을 사용하거나 사용자 고유의 파일을 만들 수 있습니다.

UnitTest1

이 자습서에서는 고유한 테스트 클래스를 만듭니다. UnitTest1.cs 파일을 삭제할 수 있습니다. TestSimpleProductController.cs라는 클래스를 추가하고 코드를 다음 코드로 바꿉니다.

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;
        }
    }
}

테스트 실행

이제 테스트를 실행할 준비가 되었습니다. TestMethod 특성으로 표시된 모든 메서드가 테스트됩니다. 테스트 메뉴 항목에서 테스트를 실행합니다.

테스트 실행

테스트 Explorer 창을 열고 테스트 결과를 확인합니다.

테스트 결과

요약

이 자습서를 완료했습니다. 이 자습서의 데이터는 단위 테스트 조건에 집중하도록 의도적으로 간소화되었습니다. 더 고급 데이터 시나리오를 단위 테스트하려면 단위 테스트 시 Entity Framework 모의 ASP.NET Web API 2를 참조하세요.