I got an interesting question to the previous article on PrivateObject:
What about testing private/protected methods with Out/ByRef parameters?
The default approach one might take won't work:
Public Class X
Private Sub ByRefParam(ByRef param As Integer)
param = 5
End Sub
End Class
. . .
<TestMethod()>
Public Sub TestX1()
Dim x As New X
Dim xAccessor As New PrivateObject(x)
Dim param As Integer
xAccessor.Invoke("ByRefParam", {param})
Assert.AreEqual(5, param)
End Sub
This test will fail with the message that 5 is not equal to 0.
The problem here is that the array of parameters passed by Invoke to ByRefParam (here: {params})
doesn't take a reference to the param local variable, but just its value.
However, the good news is that, in the above, we do have variables that are passed, by reference, to ByRefParam -
the individual entries in the array of parameters itself!
This test does pass:
<TestMethod()>
Public Sub TestX2()
Dim x As New X
Dim xAccessor As New PrivateObject(x)
Dim params As Object() = {Nothing}
xAccessor.Invoke("ByRefParam", params)
Assert.AreEqual(5, params(0))
End Sub
Here, we test ByRefParam's parameter as if it were an Out parameter - because that's how it is implemented.
And thanks to this, it doesn't really matter what values params are initialized to in the test method...
If ByRefParam was implemented as a non-Out parameter, for instance like this:
Public Class X
Private Sub ByRefParam(ByRef param As Integer)
param += 5
End Sub
End Class
Then both of these would pass:
<TestMethod()>
Public Sub TestX3()
Dim x As New X
Dim xAccessor As New PrivateObject(x)
Dim params As Object() = {Nothing}
xAccessor.Invoke("ByRefParam", params)
Assert.AreEqual(5, params(0))
End Sub
Public Sub TestX4()
Dim x As New X
Dim xAccessor As New PrivateObject(x)
Dim params As Object() = {5}
xAccessor.Invoke("ByRefParam", params)
Assert.AreEqual(10, params(0))
End Sub
Happy testing!
Top
|