0

我刚刚开始使用 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

编辑:

测试控制器操作时,如何让视图模型使用假服务类?

我应该放弃第一个构造函数并始终从控制器传入服务还是有其他方法?

干杯,
尼克

4

2 回答 2

3

我可能正在分裂头发,但我会说您的模型更像是域模型而不是视图模型。移除对 的依赖IPortalClientService,或者至少不要让模型自己实例化它。

我更喜欢将此类依赖项从视图中移除,并移至控制器。

于 2009-09-15T13:12:36.460 回答
0

实际上,这是我们在面向公众的 API 中一直使用的一种模式,并展示了依赖注入的良好使用。我会在没有问题的代码审查中通过这个。

您的实现为用户提供了灵活创建对象的选项,并提供了可测试性。

唯一的“问题”是您的测试不能轻易地覆盖第一个构造函数中的一行代码,但这只是一个问题,如果您有一个对代码覆盖率非常狂热的人——这通常本身就是一个问题。

于 2009-07-15T16:33:21.340 回答