1
Public Class PhotoUploadController

   Public ReadOnly Property IsMobileDevice As Boolean
       Get
          Return ControllerContext.HttpContext.GetOverriddenBrowser.IsMobileDevice
       End Get
   End Property

   Function SavePhoto(model As PhotoUploadModel) As ActionResult
       If Not String.IsNullOrWhiteSpace(Request.Files(0).FileName) And IsMobileDevice Then
    Return View("Index", model)
   End If       
   End Function

End Class   

<TestMethod()>
 Public Sub SavePhoto_Test()

   Dim permissions As New List(Of String)
   permissions.Add(Constants.VIEW_ACCOUNTS)
   Dim mUser As New MockUser(ListOfPermissions:=permissions)
   Dim controller As PhotoUploadController = New PhotoUploadController(mUser, New PhotoRepository)
   System.Web.HttpContext.Current = New HttpContext(New HttpRequest("test", "http://www.yahoo.com/accounts", ""), New HttpResponse(New System.IO.StringWriter()))

   Dim browserMock = MockRepository.GenerateStub(Of HttpBrowserCapabilities)()
   browserMock.Expect(Function(b) b.IsMobileDevice).Return(True)
   System.Web.HttpContext.Current.Request.Browser = browserMock

   Dim currentContext As HttpContextBase = MockRepository.GenerateStub(Of HttpContextWrapper)(System.Web.HttpContext.Current)
   currentContext.Expect(Function(fn) fn.Request.Files(0).FileName).Return("test.txt")
   'If I comment out the two lines above and uncomment the below line the IsMobile is set in the SavePhoto actionresult otherwise it is null.
   'Dim currentContext As HttpContextBase = New HttpContextWrapper(System.Web.HttpContext.Current)
   controller.ControllerContext = New ControllerContext(currentContext, New System.Web.Routing.RouteData(), controller)

   Dim model As New PhotoUploadModel(mUser)

   Dim result As ActionResult = controller.SavePhoto(model)

   Assert.IsNotNull(result)
   Assert.IsInstanceOfType(result, GetType(ViewResult))

End Sub
4

1 に答える 1

1

以下の回答は、正しい方向に導くはずです。 私は VB.NET 開発者ではないことに注意してください。構文が正しくない場合は、ご容赦ください。私は実際にC#をVBに変換するツールを使用しました:)

まず、単体テストに関する問題はほとんどありません

を。テスト メソッド名の記述が不十分であり、正確な意図が反映されていません。

b. スタブ/期待値を設定するのは簡単ではありません

ControllerContext.HttpContext.GetOverriddenBrowser.IsMobileDevice

GetOverriddenBrowser は静的拡張メソッドです。したがって、嘲笑することはできません。

c. あなたのアサートは2つのことを確認しています。1 つ目は結果が null かどうか、2 つ目は結果の型が ViewResult かどうかです。私は個人的に後者をテストします。これは結果のタイプです。結果がそうでない場合、テストは何らかの方法で例外をスローします。アサートを 1 つに制限することで、テスト メソッド名を簡単に記述できます。

.IsMobileDevice をスタブ化する手間を避けるために、コントローラーにプロパティ/多かれ少なかれ Func/delegate プロパティを導入するだけです。そして、以下のようにコンストラクターで IsMobileDevice を設定します。このようにして、単体テストで IsMobileDeviceFunc から返される値を簡単にスタブ化できます。

Imports System.Web.WebPages

Public Interface IUser
End Interface

Public Interface IPhotoRepository
End Interface

Public Class PhotoUploadModel
End Class

Public Class PhotoUploadController
    Inherits Controller

    Private m_IsMobileDeviceFunc As Func(Of Boolean)

    Public Sub New(user As IUser, repository As IPhotoRepository)
        IsMobileDeviceFunc = Function() 
        ControllerContext.HttpContext.GetOverriddenBrowser().IsMobileDevice
    End Sub

    Public Property IsMobileDeviceFunc() As Func(Of Boolean)
        Get
            Return m_IsMobileDeviceFunc
        End Get
        Set(value As Func(Of Boolean))
           m_IsMobileDeviceFunc = Value
        End Set
    End Property


    Public Function SavePhoto(model As PhotoUploadModel) As ActionResult
       Dim isMobD = IsMobileDeviceFunc

       If Not String.IsNullOrWhiteSpace(Request.Files(0).FileName) And isMobD() Then
           Return View("Index", model)
       End If

       Return New EmptyResult()
    End Function

End Class

単体テスト

 <TestMethod()> Public Sub SavePhoto_ActionExecute_ActionResultIsTypeOfViewResult()

    Dim sut = New PhotoUploadController(MockRepository.GenerateStub(Of IUser)(), MockRepository.GenerateStub(Of IPhotoRepository)())
    sut.IsMobileDeviceFunc = Function() True
    Dim currentContext = MockRepository.GenerateStub(Of HttpContextBase)()
    Dim requestStub = MockRepository.GenerateStub(Of HttpRequestBase)()
    requestStub.Expect(Function(x) x.Files(0).FileName).[Return]("foo")
    currentContext.Expect(Function(x) x.Request).[Return](requestStub)
    sut.ControllerContext = New ControllerContext(currentContext, New RouteData(), sut)

    Dim result As ActionResult = sut.SavePhoto(New PhotoUploadModel())

    Assert.IsInstanceOfType(result, GetType(ViewResult))
 End Sub

ここに画像の説明を入力

これがあなたを正しい方向に向けることを願っています。

于 2013-11-16T04:24:11.823 に答える