views:

146

answers:

4

This seems like an easy enough issue but I can't seem to find the keywords to effect my searches.

I'm trying to unit test by mocking out all objects within this method call. I am able to do so to all of my own creations except for this one:

public void MyFunc(MyVarClass myVar)
{
    Image picture;
    ...

    picture = Image.FromStream(new MemoryStream(myVar.ImageStream));

    ...
}

FromStream is a static call from the Image class (part of c#). So how can I refactor my code to mock this out because I really don't want to provide a image stream to the unit test.

+3  A: 

You can create an IImageLoader interface. The "normal" implementation just calls Image.FromStream, while your unit test version can do whatever you need it to do.

Dean Harding
That would mean I'd have to create an interface for each static method call I'd make to different classes.I'm hoping there's a more elegant way to do this...
Joe
Nope, no elegant way to get around this in a statically compiled language without runtime help. There IS a way to do this by tapping into the profiling CLR API(very complicated). This is how TypeMock works
CVertex
Apart from CVertex's solution of using TypeMock, there really isn't a way. Static methods and unit testing don't really go together very well.
Dean Harding
+1  A: 

You could wrap the static function into Func type property which can be set by the unit test with a mock or stub.

public class MyClass
{
    ..

    public Func<Image, MemoryStream> ImageFromStream = 
                                     (stream) => Image.FromStream(stream);


    public void MyFunc(MyVarClass myVar)
    {
        ...

        picture = ImageFromStream(new MemoryStream(myVar.ImageStream));

        ...
    }


    ..
}
tarn
I think like the wrapping up into an interface idea, this solution doesn't scale very well if i was to have multiple instances of static calls through out my code.I would have to create a function for every static call. Is there no way to mock out static methods from a library class?
Joe
You would only need to create a property for different static methods as you could reuse them. I believe TypeMock can mock static methods, using some IL weaving, but it is not free. Decoupling code to be testable can take quite a lot of work in C# I'm afraid.
tarn
After some thought, both the interface and function solutions offered were messy but this function solution took less lines than creating a new interface and class for just mocking out one static function. So I'm going with this one. Thanks for all the answers.
Joe
+2  A: 

Moq and most other mocking frameworks don't support mocking out static methods. However, TypeMock does support mocking out static methods and that might be of interest to you if you're willing to purchase it. Otherwise, you'll have to refactor so that an interface can be mocked...

mezoid
Moles from MSR plays in this space too
Ruben Bartelink
+1  A: 

This can be acheived with Moles, a Visual Studio 2010 Power Tools. The Moles code would look like this:

// replace Image.FromStream(MemoryStream) with a delegate
MImage.FromStreamMemoryStream = stream => null; 
Peli