1

I'm writing a set of unit tests for a large, complex class called ImageEditor from a piece of legacy code, where image processing and GUI functionality isn't strictly divided. One of the methods in the class, BaseImageChanged, seems to be concerned entirely with how images get displayed and should be disabled in my unit tests to avoid unnecessary complexity. The test project is in C#, and the original code is in VB; my idea was to create a Decorator for the class in C# and then hide the method behind an empty one that does nothing. However, when I try running the unit test, the VB code keeps referencing the old BaseImageChanged method as though the replacement didn't exist. Here's what I'm doing:

(VB class)

Public Class ImageEditor
  ...
  Public Sub BaseImageChanged()
  ...
  End Sub
  ...
End Class

(C# class)

class ImageEditorTestingClass : ImageEditor_Accessor
{
   public new void BaseImageChanged() {}
}

Is there a way to accomplish this sort of interoperability, or will I have to find another way?

EDIT: The compiler error turned out to be a problem with reflection. Also, overriding the method didn't work as long as the base class was an accessor of ImageEditor instead of the original ImageEditor class.(No compiler error, but the base method's behavior wasn't overridden.)

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
estanford
  • 1,302
  • 1
  • 13
  • 23
  • 1
    Shouldn't `ImageEditorTestingClass` inherit from `ImageEditor`? It's inheriting from `ImageEditor_Accessor`. – Jordão Apr 20 '11 at 16:29
  • Then, just make `ImageEditor.BaseImageChanged` `Overridable` and mark `ImageEditorTestingClass.BaseImageChanged` as `override` instead of `new`. – Jordão Apr 20 '11 at 16:37
  • @Jordão: ImageEditor_Accessor is a class that gets automatically by MSTest, which is supposed to be the same as ImageEditor except that it gives public access to ImageEditor's private members. It turned out to be the reason why the derived method didn't override the base method, though. – estanford Apr 20 '11 at 17:12
  • Thanks for the explanation. I never used MSTest, only NUnit. And I don't normally need to access private members of a class for testing. – Jordão Apr 20 '11 at 17:30

3 Answers3

1

Do you have access to the VB code? if so mark it virtual (C# syntax); Then in the C# code override it with an empty body so that id does nothing.

You should (almost) never use 'new' to redeclare methods or properties. If some code is assuming it's the base class, even if you pass a derived one, the base methods will be called.

For better understanding read about late-binding and early-binding in .NET

Early and late binding

It seems @estanford accepted this answer due to my comment below

"Where you call BaseImageChanged try using reflection"

Community
  • 1
  • 1
Luis Filipe
  • 8,488
  • 7
  • 48
  • 76
0

I don't know VB at all, but this sounds more like a case for a virtual method with an override than a method hiding. The VB code is probably calling "this.BaseImageChanged()" somewhere, which wouldn't call your new method... right?

NateTheGreat
  • 2,295
  • 13
  • 9
  • There's no calls of the form "this.BaseImageChanged", just "BaseImageChanged". In any case, I end up with much the same problem if I try to override; changing the VB method declaration to "Overridable Sub BaseImageChanged()" and the C# method to "public override void BaseImageChanged(){}" gives a compiler error that says "there is no suitable method for override". – estanford Apr 20 '11 at 16:18
  • @estanford: Some stupid question, does the c# class derives from the VB one? – Luis Filipe Apr 20 '11 at 16:20
  • The same thing will happen if they call `((BaseClass)SubClass).BaseImagechanged`, which will happen if you did a rifled through a `List` with `foreach(BaseClass c in yourList)`. What does the test call look like? – Pete M Apr 20 '11 at 16:21
  • @Pete: The test never calls BaseImageChanged explicitly, but BaseImageChanged gets called by another method, FlipLR, which is the method that I'm interested in testing. – estanford Apr 20 '11 at 16:27
0

It looks like what's going on here is that

  1. You have a library written in VB.Net
  2. Your unit tests are written in C# and are using MSTest
  3. You're trying to derive from the generated accessor instead of the original class

In this case the only option you have is to use new. The generated accessor class will not add virtual methods and hence if you want to provide an alternate method with the same name new is the only way to do so.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454