【发布时间】:2011-11-13 18:12:51
【问题描述】:
我正在尝试使用 Moq 在一个看起来像这样的类上编写一些单元测试:
Public Interface IAwesomeInterface
Function GetThis() As Integer
Function GetThisAndThat(ByVal that As Integer) As Integer
End Interface
Public Class MyAwesomeClass
Implements IAwesomeInterface
Dim _this As Integer
''' <summary>
''' injection constructor
''' </summary>
Private Sub New(ByVal this As Integer)
Me._this = this
End Sub
''' <summary>
''' default factory method
''' </summary>
Public Shared Function Create() As IAwesomeInterface
Return New MyAwesomeClass(42)
End Function
Public Overridable Function GetThis() As Integer Implements IAwesomeInterface.GetThis
Return _this
End Function
Public Function GetThisAndThat(ByVal that As Integer) As Integer Implements IAwesomeInterface.GetThisAndThat
Return GetThis() + that
End Function
End Class
- 参数化构造函数是私有的或内部的
- 两种方法之一依赖于另一种方法的结果
我想检查当GetThisOrThat 被调用时,它实际上调用了GetThis。但我也想模拟 GetThis 以便它返回一个特定的众所周知的值。
对我来说,这是一个 Partial Mocking 的例子,我们基于一个类创建一个 Mock,并为构造函数传递参数。这里的问题是没有公共构造函数,因此,Moq 不能调用它...... 我尝试使用 Visual Studio 为 MSTest 生成的访问器,并使用这些访问器进行模拟,这就是我想出的:
<TestMethod()>
Public Sub GetThisAndThat_calls_GetThis()
'Arrange
Dim dummyAwesome = New Mock(Of MyAwesomeClass_Accessor)(56)
dummyAwesome.CallBase = True
dummyAwesome.Setup(Function(c) c.GetThis()).Returns(99)
'Act
Dim thisAndThat = dummyAwesome.Object.GetThisAndThat(1)
'Assert
Assert.AreEqual(100, thisAndThat)' Expected:<100>. Actual:<57>.
dummyAwesome.Verify(Function(d) d.GetThis, Times.Once, "GetThisAndThat should call GetThis")
End Sub
...但这失败了。执行测试时,GetThis 返回 56 而不是 99。
我做错了什么吗? 在我阅读的其他问题中,我没有看到提到这种情况。
更新:基于 Tim Long 的回答
我将此添加到我正在测试的程序集的 AssemblyInfo.vb 中:
<Assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")>
(不包括 PublicKey,即不像文档中指定的那样:http://code.google.com/p/moq/wiki/QuickStart in Advanced Features)
并制作了构造函数Friend (=internal) 而不是Private。
我现在可以直接使用 internal 构造函数,而不是使用 MSTests Accessors :
<TestClass()>
Public Class MyAwesomeTest
<TestMethod()>
Public Sub GetThisAndThat_calls_GetThis()
'Arrange
Dim dummyAwesome = New Mock(Of MyAwesomeClass)(56)
dummyAwesome.CallBase = True
dummyAwesome.Setup(Function(c) c.GetThis()).Returns(99)
'Act
Dim thisAndThat = dummyAwesome.Object.GetThisAndThat(1)
'Assert
Assert.AreEqual(100, thisAndThat)
dummyAwesome.Verify(Function(d) d.GetThis, Times.Once, "GetThisAndThat should call GetThis")
End Sub
End Class
【问题讨论】:
标签: .net vb.net unit-testing moq mstest