2011-09-09 70 views
1

我试图写一个类,它看起来像这样一些单元测试类的部分模拟,使用起订量:与私有构造

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,以便它返回一个特定的知名价值。

对我来说,这是部分模拟的一个例子,我们在这里创建一个基于类的模拟,为构造函数传递参数。这里的问题是,没有公共构造函数,因此,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.

我做错了什么? 在我阅读的其他问题中,我没有看到提及这种场景。

UPDATE:由蒂姆·朗基于答案

我已将此添加组件的AssemblyInfo.vb我测试:

<Assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")> 

(不包括公钥,即不喜欢在规定文档:http://code.google.com/p/moq/wiki/QuickStart in 高级功能

并制作了构造函数Friend(= internal)而不是Private。 我现在可以直接使用,而不是使用MSTests Accessor S中internal构造:

<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 

回答

2

你可以让你的构造函数内部,而不是私有,然后使用InternalsVisibleTo属性来指定单元测试作为“朋友组装” 。

或者,它可能是值得考虑的Moles isolation framework(MS研究)

+0

我曾试图标志着构造函数'internal'(ie'Friend'),并设置InternalsVisibleTo根据MOQ(即DynamicProxyGenAssembly2的文件与' PublicKey'),并且失败,出现错误System.NotSupportedException:父没有默认构造函数。默认的构造函数必须明确定义。虽然不包括公开密钥,但是......非常感谢! – tsimbalar