Rishi Tiwari
Rishi Tiwari

Reputation: 1041

How to mock a DLL Import

I'm trying to write unit test case of a class which uses Dll imports like below

 [DllImport("user32.dll")]
 public static extern IntPtr FindWindow(string name, string windowName);

In order to test the class I want to mock the above statement using MOQ but not able to figure out how to setup a mock for it.

Also would like to know whether the above is achievable or not..if not then what needs to be done in order to make it testable.

I know that to make this class testable we need to create wrappers over these statements and would need to separate it out in a separate class.

Would like to know is there any other option to achieve the same.

Upvotes: 1

Views: 2939

Answers (2)

JamesR
JamesR

Reputation: 745

actually you can mock methods from exported Dlls by using typemock Isolator, and without any unnecessary changes in your code. you just need to export the Dll and mock the method as any other static method, for example:

public class ClassUnderTest
    {

        public bool foo()
        {
            if(Dependecy.FindWindow("bla","bla") == null)
            {
                throw new Exception();
            }
            return true;
        }
    }

public class Dependecy
{//imported method from dll
     [DllImport("user32.dll")]
     public static extern IntPtr FindWindow(string name, string windowName);
 }

        [TestMethod]
        public void TestMethod1()
        {
            //setting a mocked behavior for when the method will be called
            Isolate.WhenCalled(() => Dependecy.FindWindow("", "")).WillReturn(new IntPtr(5));

            ClassUnderTest classUnderTest = new ClassUnderTest();
            var res = classUnderTest.foo();

            Assert.IsTrue(res);
        }

You can see more about Pinvoked Methods here

Upvotes: 3

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

You can´t mock a static method but only interfaces or classes with virtual members. However you can wrap the method into a virtual one that you can wrap:

interface StaticWrapper
{
    InPtr WrapStaticMethod(string name, string windowName);
}
class MyUsualBehaviour : IStaticWrapper
{
    public InPtr WrapStatic(string name, string windowName)
    {
        // here we do the static call from extern DLL
        return FindWindow(name, widnowName);
    }
}

However you can now mock that interface instead of the static method:

var mock = new Moq<IStaticWrapper>();
mock.Setup(x => x.WrapStatic("name", "windowName")).Returns(whatever);

Furthermore you aren´t calling the extern method in your code but only the wrapper which reduces code-coupling to that specific library.

See this link for further explanation an idea: http://adventuresdotnet.blogspot.de/2011/03/mocking-static-methods-for-unit-testing.html

Upvotes: 1

Related Questions