컨트롤러 작업에 대한 단위 테스트를 만드는 방법을 알아봅니다. 이 자습서에서 Stephen Walther는 컨트롤러 작업이 특정 뷰를 반환하는지, 특정 데이터 집합을 반환하는지, 다른 유형의 작업 결과를 반환하는지 테스트하는 방법을 보여 줍니다.
이 자습서의 목표는 ASP.NET MVC 애플리케이션에서 컨트롤러에 대한 단위 테스트를 작성하는 방법을 보여 주는 것입니다. 세 가지 유형의 단위 테스트를 빌드하는 방법에 대해 설명합니다. 컨트롤러 작업에서 반환된 뷰를 테스트하는 방법, 컨트롤러 작업에서 반환된 데이터 보기 작업을 테스트하는 방법 및 컨트롤러 작업 중 하나가 두 번째 컨트롤러 작업으로 리디렉션되는지 여부를 테스트하는 방법을 알아봅니다.
테스트 아래에 컨트롤러 만들기
먼저 테스트하려는 컨트롤러를 만들어 보겠습니다. 라는 ProductController
컨트롤러는 목록 1에 포함되어 있습니다.
목록 1 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
Return View("Details")
End Function
End Class
에는 ProductController
및 라는 두 개의 작업 메서드가 Index()
포함되어 있습니다 Details()
. 두 작업 메서드 모두 뷰를 반환합니다.
Details()
작업은 Id라는 매개 변수를 허용합니다.
컨트롤러에서 반환된 뷰 테스트
가 올바른 보기를 반환하는지 여부를 ProductController
테스트한다고 상상해 보십시오. 작업이 호출될 때 ProductController.Details()
세부 정보 보기가 반환되는지 확인하려고 합니다. 목록 2의 테스트 클래스에는 작업에서 반환된 뷰를 테스트하기 위한 단위 테스트가 포함되어 있습니다 ProductController.Details()
.
목록 2 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsView()
Dim controller As New ProductController()
Dim result As ViewResult = controller.Details(2)
Assert.AreEqual("Details", result.ViewName)
End Sub
End Class
목록 2의 클래스에는 라는 TestDetailsView()
테스트 메서드가 포함되어 있습니다. 이 메서드에는 세 줄의 코드가 포함되어 있습니다. 첫 번째 코드 줄은 클래스의 ProductController
새 instance 만듭니다. 두 번째 코드 줄은 컨트롤러의 Details()
작업 메서드를 호출합니다. 마지막으로, 마지막 코드 줄은 작업에서 반환된 Details()
뷰가 세부 정보 보기인지 여부를 확인합니다.
속성은 ViewResult.ViewName
컨트롤러에서 반환된 뷰의 이름을 나타냅니다. 이 속성 테스트에 대한 한 가지 큰 경고입니다. 컨트롤러에서 보기를 반환할 수 있는 두 가지 방법이 있습니다. 컨트롤러는 다음과 같은 보기를 명시적으로 반환할 수 있습니다.
Function Details(ByVal Id As Integer)
Return View("Details")
End Function
또는 다음과 같이 컨트롤러 작업의 이름에서 뷰 이름을 유추할 수 있습니다.
Function Details(ByVal Id As Integer)
Return View()
End Function
이 컨트롤러 작업은 라는 Details
뷰도 반환합니다. 그러나 뷰의 이름은 작업 이름에서 유추됩니다. 뷰 이름을 테스트하려면 컨트롤러 작업에서 뷰 이름을 명시적으로 반환해야 합니다.
키보드 조합 Ctrl-R, A 를 입력하거나 솔루션에서 모든 테스트 실행 단추를 클릭하여 목록 2 에서 단위 테스트를 실행할 수 있습니다 (그림 1 참조). 테스트가 통과하면 그림 2에 테스트 결과 창이 표시됩니다.
그림 01: 솔루션에서 모든 테스트 실행(전체 크기 이미지를 보려면 클릭)
그림 02: 성공! (전체 크기 이미지를 보려면 클릭)
컨트롤러에서 반환된 데이터 보기 테스트
MVC 컨트롤러는 라는 View Data
항목을 사용하여 뷰에 데이터를 전달합니다. 예를 들어 작업을 호출할 때 특정 제품에 대한 세부 정보를 표시한다고 상상해 보십시오 ProductController Details()
. 이 경우 모델에 정의된 클래스의 Product
instance 만들고 를 활용하여 View Data
instance Details
뷰에 전달할 수 있습니다.
목록 3에서 수정된 ProductController
에는 제품을 반환하는 업데이트 Details()
된 작업이 포함됩니다.
목록 3 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
Dim product As New Product(Id, "Laptop")
Return View("Details", product)
End Function
End Class
먼저 작업은 Details()
랩톱 컴퓨터를 나타내는 클래스의 Product
새 instance 만듭니다. 다음으로 클래스의 Product
instance 메서드에 두 번째 매개 변수로 View()
전달됩니다.
단위 테스트를 작성하여 예상 데이터가 뷰 데이터에 포함되어 있는지 여부를 테스트할 수 있습니다. 목록 4의 단위 테스트는 작업 메서드를 호출 ProductController Details()
할 때 랩톱 컴퓨터를 나타내는 제품이 반환되는지 여부를 테스트합니다.
목록 4 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsViewData()
Dim controller As New ProductController()
Dim result As ViewResult = controller.Details(2)
Dim product As Product = result.ViewData.Model
Assert.AreEqual("Laptop", product.Name)
End Sub
End Class
목록 4에서 메서드는 TestDetailsView()
메서드를 호출하여 반환된 데이터 보기를 테스트합니다 Details()
. 는 ViewData
메서드를 호출하여 반환된 ViewResult
의 속성으로 노출됩니다 Details()
. 속성에는 ViewData.Model
보기에 전달된 제품이 포함됩니다. 이 테스트는 단순히 데이터 보기에 포함된 제품에 Laptop이라는 이름이 포함되어 있음을 확인합니다.
컨트롤러에서 반환된 작업 결과 테스트
더 복잡한 컨트롤러 작업은 컨트롤러 작업에 전달된 매개 변수의 값에 따라 다양한 유형의 작업 결과를 반환할 수 있습니다. 컨트롤러 작업은 , RedirectToRouteResult
또는 JsonResult
를 비롯한 다양한 유형의 작업 결과를 반환할 ViewResult
수 있습니다.
예를 들어 목록 5의 수정된 Details()
작업은 유효한 제품 ID를 작업에 전달할 때 보기를 반환 Details
합니다. 값이 1보다 작은 ID인 잘못된 제품 ID를 전달하면 작업으로 Index()
리디렉션됩니다.
목록 5 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
If Id < 1 Then
Return RedirectToAction("Index")
End If
Dim product As New Product(Id, "Laptop")
Return View("Details", product)
End Function
End Class
목록 6에서 Details()
단위 테스트를 사용하여 작업의 동작을 테스트할 수 있습니다. 목록 6의 단위 테스트는 값이 -1인 ID가 메서드에 Index
전달될 때 보기로 Details()
리디렉션되는지 확인합니다.
목록 6 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsRedirect()
Dim controller As New ProductController()
Dim result As RedirectToRouteResult = controller.Details(-1)
Assert.AreEqual("Index", result.Values("action"))
End Sub
End Class
컨트롤러 작업에서 메서드를 호출 RedirectToAction()
하면 컨트롤러 작업은 를 반환합니다 RedirectToRouteResult
. 테스트는 가 RedirectToRouteResult
사용자를 라는 Index
컨트롤러 작업으로 리디렉션할지 여부를 확인합니다.
요약
이 자습서에서는 MVC 컨트롤러 작업에 대한 단위 테스트를 빌드하는 방법을 알아보았습니다. 먼저 컨트롤러 작업에서 올바른 보기를 반환하는지 확인하는 방법을 알아보았습니다. 속성을 사용하여 ViewResult.ViewName
보기의 이름을 확인하는 방법을 알아보았습니다.
다음으로, 의 View Data
콘텐츠를 테스트하는 방법을 검토했습니다. 컨트롤러 작업을 호출한 후 올바른 제품이 반환 View Data
되었는지 여부를 검사 방법을 알아보았습니다.
마지막으로 컨트롤러 작업에서 다양한 유형의 작업 결과가 반환되는지 여부를 테스트하는 방법을 설명했습니다. 컨트롤러가 를 반환하는지 또는 를 반환 ViewResult
하는지 테스트하는 RedirectToRouteResult
방법을 알아보았습니다.