1

We have a VB.net function with the following signature in class InitializerFactory:

Public Shared Function Create(ByRef ui As Object) As IModeInitializer

I'm attempting to test this function by passing in a mock of ui (using Rhino Mocks):

MainForm ui = mocks.StrictMock<MainForm>();
IModeInitializer item = InitializerFactory.Create(ref ui);

When attempting to pass ui as a parameter, I get the following errors:

  • The best overloaded method match for 'InitializerFactory.Create(ref object)' has some invalid arguments
  • Argument '1': cannot convert from 'ref MainForm' to 'ref object'

Ideally, the solution would be to extract an interface on UI (or its class, MainForm) but that's not doable by any means - it's an extremely bloated class.

I also can't declare ui as an Object, or else I can't mock the methods inside of it since the methods don't belong to an Object type.

My question is -- what am I doing wrong?

MunkiPhD
  • 3,636
  • 1
  • 29
  • 51

1 Answers1

3

This is just because of the ref parameter syntax. The problem is that the function has to be able to set ANY type of object, since it's a by ref parameter. You can't just pass it a reference to a MainForm, which is what you're attempting.

Unfortunately, this is a pretty difficult API to work with.

You can handle this by assigning your instance to an object first:

MainForm ui = mocks.StrictMock<MainForm>();
object uiObj = ui;
IModeInitializer item = InitializerFactory.Create(ref uiObj);
if (uiObj != ui) { 
    // Handle the case where the reference changed!
    ui = uiObj as MainForm; // May be null, if it's no longer a "MainForm"
}

If you want to fully understand this, you can read up on Covariance and Contravariance.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • I've tried this, but then I get the following error in NUnit: **System.InvalidOperationException : The object '' is not a mocked object.** I'm assuming that it's talking about the uiObj since it's not just an Object as opposed to a mock object. – MunkiPhD Oct 06 '09 at 16:20
  • It would really help if you'd say where that error occurred. But I agree with Reed - it sounds like a horrible API. Does it really have to have a by-ref parameter? – Jon Skeet Oct 06 '09 at 16:25
  • @MunkiPhD: That's not the problem. Casting and assigning to object doesn't change the actual type of object. You have some other issue going on inside of the method. – Reed Copsey Oct 06 '09 at 17:29
  • Yea, the API isn't the greatest in some areas, but 'it is what it is.' – MunkiPhD Oct 06 '09 at 17:53