Reusable test base classes
(This applies to ASP.NET MVC and MSTest and Moq)
When writing tests for MVC controllers that inherit from the same base, you can save yourself some time by creating a test base class that is responsible for setup and teardown of your test cases:
1) Create an abstract class that takes your base controller class as a templated argument
2) Create a public method that initializes your tests. Adorn this with TestInitialize.
3) Create a public method that cleans up after your tests. Adorn this with TestCleanup.
4) Create an abstract method that initializes your controller.
Having done this, you can focus the test cases, rather than the boilerplate in your tests, simply having to override the CreateController method (step 4 above) to initialize your particular controller, given the initialized argument passed.
Example Base Class
Imports SecretCompany.Web.ControllersImports Moq
Namespace ControllerTests
Public MustInherit Class ControllerTestBase(Of TController As BaseController)
Protected RepositoryMock As Mock(Of ISecretRepository)
Protected State As State
Protected Controller As TController
Protected MustOverride Function CreateController(mockedRepository As ISecretRepository, fakeState As State) As TController
'''
''' http://connect.microsoft.com/VisualStudio/feedback/details/555442/visual-studio-mstest-allows-testinitialize-s-to-appear-inside-of-non-testclass-s-while-mstest-exe-does-not
'''
Public Sub TestInitialize()
RepositoryMock = New Mock(Of ISecretRepository)
State = New State("bananas")
Controller = CreateController(RepositoryMock.Object, State)
End Sub
'''
''' http://connect.microsoft.com/VisualStudio/feedback/details/555442/visual-studio-mstest-allows-testinitialize-s-to-appear-inside-of-non-testclass-s-while-mstest-exe-does-not
'''
Public Sub TestCleanup()
Controller.Dispose()
End Sub
End Class
End Namespace
Example Test Class
Imports SecretCompany.Common.Global.KonstanterImports SecretCompany.Web.Controllers
Imports Moq
Imports System.Web.Mvc
Namespace ControllerTests
Public Class SecretControllerTests : Inherits ControllerTestBase(Of SecretController)
Protected Overrides Function CreateController(ByVal mockedRepository As ISecretRepository, ByVal fakeState As State) As SecretController
Return New SecretController(mockedRepository, fakeState)
End Function
Public Sub Index_Calls_Repository_CreateViewModel()
Const expectedId = "70CD7009-CEE3-44DD-AF69-7416DC5B522E"
Const expectedDate = "1981-12-29 13:37"
Const expectedCode = Codes.SecretCode1
Controller.Index(expectedId, expectedDate)
RepositoryMock.Verify(Sub(mock) mock.CreateViewModel(
It.IsAny(Of SkadehandelseBaseViewModel),
It.IsInRange(DateTime.Now.AddMinutes(-1), DateTime.Now.AddMinutes(1), Range.Exclusive),
expectedId,
expectedCode,
expectedDate,
State.Ticket()), Times.Once())
End Sub
Public Sub Index_Returns_View()
Const expectedDate = "1981-12-29 13:37"
Dim result = Controller.Index(It.IsAny(Of String), expectedDate)
Dim viewResult = TryCast(result, ViewResult)
Assert.IsNotNull(viewResult)
End Sub
End Class
End Namespace
Comments