chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hello,

Recently I had to find out, that creating mocked objects for internal interfaces fails. It does not matter wheter the interface is placed in the same assembly as the test-code or in an other one using the InternalsVisibleToAttribute.

Steps to Reproduce:

1. Insert the following interface in your TestProject (non-nested):
internal interface ITest
{
    void BlaBlubb();
}


2. Try to create a mocked object using either
MockObject MockedInternalInterface = MockManager.MockObject(typeof(ITest), false);
ITest Test = (ITest)MockedInternalInterface.Object;

or
ITest Test = (Itest)RecorderManager.CreateMockedObject(typeof(ITest));


Expected Results:
-> Test should contain the mocked object derived from the given interface.

Actual results:
-> The following TypeLoadException is thrown:

Der Typ Mocktest in der Assembly DynamicMockAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null versucht, eine Schnittstelle zu implementieren, auf die nicht zugegriffen werden kann.

bei System.Reflection.Emit.TypeBuilder.TermCreateClass(Int32 handle, Module module)
bei System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
bei System.Reflection.Emit.TypeBuilder.CreateType()
bei t.a(Type A_0, Object[] A_1)
bei TypeMock.MockManager.MockObject(Type type, Constructor mockConstructors, Object[] args)
bei TypeMock.MockManager.MockObject(Type type, Object[] args)
bei TypeMock.RecorderManager.CreateMockedObject(Type typeToMock)
bei epiSource.Common.SystemImageListTest.Init() in D:ProjekteSrcMeine Projektes2005ProjectsepiSource.CommonepiSource.WinAPITestManagedSystemImageListTestSystemImageListTest.cs:Zeile 32.


Workaround:

Create an (internal or public) class derived from ITest. Nearly no code needs to be written, as Visual Studio does this using the implement interface feature. This class can now be mocked.[/quote]
asked by philipp (2.9k points)

3 Answers

0 votes
One more thing related to this issue: When using RecorderManager.CreateMockedObject([..]) together with TestRunner, TestRunner does not recognize, that the test finished. It always thinks it has not yet run (Might also hapen when using NUnit GUI, but I did not test this).

/edit: Actually the Test is not finished. This can be seen when stepping through the test with the debugger. When CreateMockedObject([..]) is not used, one can step through until the end of the function (C#: "}") is reached - otherwhise execution stops after the last command in the function and the closing "}" is not reached!
answered by philipp (2.9k points)
0 votes
Your workaround is quite correct, if you are making an internal interface you are going to create the derived class internally. So just mock that class.

If you are using .NET 2.0 you can also mock the internal interfaces if you give TypeMock the correct permissions, as follows:

In the AssemblyInfo of the internal interface add
[assembly: InternalsVisibleTo("DynamicMockAssembly")]


The DynamicMockAssembly is the assembly where TypeMock creates all the concrete classes derived from interfaces and abstract classes.

About the second issue, we are aware with problems using Natrual Mocks and TestRunner, I will send you a fix offline.
answered by scott (32k points)
0 votes
Thanks for this quick response - even on sunday :)
answered by philipp (2.9k points)
...