Intro
I am doing a kind of OCR application that should recognize characters based on pre-saved .bmp pictures of each character.
Now, for a given part of a screenshot of the screen, where I know there will be a character, I want to pass the current picture to a CharacterFactory, that will return a Character object:
class CharacterFactory : ICharacterFactory {
private Collection<Bitmap> aPictures = new HashTable<Bitmap>();
private Collection<Bitmap> bPictures = new HashTable<Bitmap>();
private Collection<Bitmap> cPictures = new HashTable<Bitmap>();
...
public CharacterFactory() {
LoadAllPictures();
}
...
public Character GetCharacter(Bitmap characterToRecognize) {
if (aPictures.Contains(characterToRecognize)) return new ACharacter();
if (bPictures.Contains(characterToRecognize)) return new BCharacter();
if (cPictures.Contains(characterToRecognize)) return new BCharacter();
...
}
}
My question is
how to Unit Test this class? The only way I can see for testing the class is indeed to save a couple of Bitmaps to pass in the characterToRecognize argument and compare them to the list of pre-saved pictures my program has. That has the problem, of course, of taking some time to load the pictures and some other time for running the GetCharacter() algorithm.
I could of course wrap each of my CharacterFactory’s xPictures Collection in a new class, but I’d just be pushing the problem to that new class.
How to deal with this kind of situations?
The problem of course, is that BitMap (like many .Net classes) is sealed. Which makes it hard for you to create a mock. What I typically do in these cases is make a very thin wrapper for these classes, something that takes a BitMap for a constructor and then mimics the methods and delegates to the BitMap. then you can either make a mock of this class, or extract a interface for it. Then make the class you want to test take your new “IBitMap” and mock it, inject your data ext just as others have said.
My projects often end up with a small collection of these “Microsoft Wrappers”. It would be so much easier if they would just include interfaces for these classes, or at least not seal them .