Модульное тестирование действий контроллера со сложными viewModels - PullRequest
0 голосов
/ 15 июля 2009

Я только начинаю работать с ASP.NET MVC, и я также новичок в модульном тестировании :) Пока все хорошо.

У меня есть действие контроллера, которое устанавливает представление индекса с помощью модели представления. Тестирование действия контроллера является простым, поскольку я могу передать поддельный класс обслуживания в конструкторе контроллера, но моя модель представления довольно сложна и извлекает свой собственный класс обслуживания при создании экземпляра.

Код должен прояснить это, я надеюсь ...

Действие контроллера:

Function Index(ByVal id As Integer?) As ActionResult
  Dim totalCount As Integer = 0
  Dim selectedClient As Integer
  If id Is Nothing Then
    selectedClient = _portalClientService.GetFirstClient().ID
  Else
    selectedClient = id
  End If
  Dim users As MembershipUserCollection = _membershipService.GetUsersByClientId(selectedClient, 0, 1000, totalCount)
  Return View(New UserListViewModel(users, selectedClient))
End Function

Класс представления модели:

Public Class UserListViewModel

  Private _clientService As IPortalClientService

  Public Sub New(ByVal users As MembershipUserCollection, ByVal selectedClient As Integer)
    Me.New(users, selectedClient, Nothing)
  End Sub

  Public Sub New(ByVal users As MembershipUserCollection, ByVal selectedClient As Integer, ByVal clientService As IPortalClientService)
    _users = users
    _clientService = If(clientService, New PortalClientService)
    _clients = New SelectList(_clientService.GetClients.OrderBy(Function(c) c.ClientName), "ID", "ClientName", selectedClient)
  End Sub

  Private _users As MembershipUserCollection
  Public Property Users() As MembershipUserCollection
    Get
      Return _users
    End Get
    Set(ByVal value As MembershipUserCollection)
      _users = value
    End Set
  End Property

  Private _clients As SelectList
  Public Property Clients() As SelectList
    Get
      Return _clients
    End Get
    Set(ByVal value As SelectList)
      _clients = value
    End Set
  End Property

End Class

EDIT:

Как при проверке действия контроллера, как заставить модель представления использовать поддельный класс обслуживания?

Должен ли я просто отказаться от первого конструктора и всегда передавать сервис из контроллера или есть другой способ?

Приветствия
Ник

Ответы [ 2 ]

3 голосов
/ 15 сентября 2009

Я, вероятно, расщепляю волосы, но я бы сказал, что ваша модель - это скорее модель предметной области, чем модель вида. Удалите зависимость от IPortalClientService или, по крайней мере, не позволяйте модели создавать ее самостоятельно.

Я предпочитаю удалять такие зависимости от представления и к контроллеру.

0 голосов
/ 15 июля 2009

На самом деле, это шаблон, который мы все время используем в наших открытых API-интерфейсах, и демонстрирует хорошее использование внедрения зависимостей. Я бы передал это в обзоре кода без проблем.

Ваша реализация дает пользователю возможность гибко создавать объект и обеспечивает тестируемость.

Единственная «проблема» состоит в том, что ваши тесты не могут легко охватить одну строку кода в первом конструкторе, но это проблема, только если у вас есть кто-то, кто фанатично относится к покрытию кода - что обычно само по себе является проблемой.

...