Test a private function with XojoUnit

If I have a class that has a really important but private function in it that I’d like to test with XojoUnit, is there a standard way to access that function from a XojoUnit test?

I was surprised (and delighted) that I could do the following to access a private function…

[code]Public Function CallFunction(Extends Obj As Object, Name As String, ParamArray Params() As Variant) as Variant
Dim result As Variant
Dim methods() As Introspection.MethodInfo = Introspection.GetType(Obj).GetMethods

For i As Integer = 0 To methods.Ubound
If methods(i).Name = Name and methods(i).GetParameters.Ubound = Params.Ubound Then
result = methods(i).Invoke(Obj, Params)
Exit For i
End If
Next

Return result
End Function
[/code]

… and use it from a test…

[code]Public Sub SelectActorTest()
Dim result As String = DB.CallFunction(“SelectActor”, “Wibble”, “Wobble”)

Assert.AreEqual "actor Wibble(Wobble) create; ", result
End Sub
[/code]

… but wondered whether there was a more performant and/or less yucky way to do it?

Create a special interface for your unit tests.

Wooooosh, straight over my head!

Can you explain a little more Kem, I’m not seeing how I could use an Interface to grant access to a private function?

[quote=315089:@Ian Jones]Wooooosh, straight over my head!

Can you explain a little more Kem, I’m not seeing how I could use an Interface to grant access to a private function?[/quote]

I never thought about XojoUnit and Interface intergrations. Inquiring minds would love to know more.

There is no requirement that a method that implements an interface’s method be pubic, so you can do it like this:

MyClass has a private method that you want to test, SomePrivateMethod. Create an Interface that defines SomePrivateMethod, then assign the Interface to your class. When you test, you can do this:

dim mc as new MyClass
dim tester as MyClassTestingInterface = mc

tester.SomePrivateMethod
...

[quote=315079:@Ian Jones]If I have a class that has a really important but private function in it that I’d like to test with XojoUnit, is there a standard way to access that function from a XojoUnit test?

I was surprised (and delighted) that I could do the following to access a private function…
[/quote]
I’m not. Not in the least.
Introspection allows you to nuke your toes if you really want to and yes it disobeys scope rules like this (which has been reported as a bug)
Until then use carefully

There are several methods to test the private function. The easier option is to test the private function through one of your public function in the class that call the function.

Another solution is to change the private function to protected and create another child class for testing purpose. This child class then can be used to test the protected function directly.

[quote=315099:@Kem Tekinay]There is no requirement that a method that implements an interface’s method be pubic, so you can do it like this:

MyClass has a private method that you want to test, SomePrivateMethod. Create an Interface that defines SomePrivateMethod, then assign the Interface to your class. When you test, you can do this:

[code]
dim mc as new MyClass
dim tester as MyClassTestingInterface = mc

tester.SomePrivateMethod

[/code][/quote]
Awesome! That works really well, it’s much better than trying to use introspection as you explicitly specify the method signature(s).

Heard loud and clear. My first inclination was that it surely couldn’t work, felt like I’d exploited a bug. I guess even using an interface to skirt scope rules could be considered a bug too.

Definitely wanted to avoid this option as the public methods have side effects (database access) that need to be tested in their own way and could also mask problems with the target private function.

This is what I expected to be the “only way”, aside from making the function public of course. I was originally thinking along the lines of changing the function to be protected and then creating a subclass that had a public function that proxied for it that could be called from the test methods on the TestGroup subclass.

In the end @Kem Tekinay came to the rescue, thank you Kem.