【问题标题】:Unit testing controller actions with complex viewModels使用复杂的 viewModel 对控制器操作进行单元测试
【发布时间】:2009-07-15 16:27:43
【问题描述】:

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

编辑:

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

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

干杯,
尼克

【问题讨论】:

    标签: asp.net-mvc unit-testing controller viewmodel


    【解决方案1】:

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

    我更喜欢将这些依赖项从视图中移除,并转移到控制器中。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 谢谢,很高兴知道我并没有走得太远 :) 主要问题是在单元测试中,我可以将假的 clientservice 类传递给控制器​​,但是 viewmodel 实例化了它自己的服务类并命中数据库。在不修改控制器操作的情况下,有什么方法可以让视图模型在测试控制器操作时使用假服务类?
      猜你喜欢
      • 2020-09-05
      • 1970-01-01
      • 2023-03-19
      • 2017-04-26
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      相关资源
      最近更新 更多