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
问问题
1073 次
1 回答
1
下面的答案应该引导您走向正确的方向。 注意我不是 VB.NET 开发人员。如果我的语法不正确,请耐心等待。我实际上使用了一个工具将 C# 转换为 VB :)
首先,您的单元测试很少出现问题
一个。您的测试方法名称写得不好,它不能反映您的确切意图。
湾。存根/设置期望值并不容易
ControllerContext.HttpContext.GetOverriddenBrowser.IsMobileDevice
GetOverriddenBrowser 是一种静态扩展方法。所以它是不可嘲笑的。
C。您的断言正在验证两件事。一是结果是否为null,二是结果的类型是ViewResult。我会亲自测试后者,结果的类型。如果结果不是,测试会以任何方式抛出异常。通过限制为一个断言,您的测试方法名称变得更易于编写。
为了避免删除 .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 回答