AddComponent of a type that was dynamically created with reflection.emit

I am trying to create a mocking framework for unit testing in Unity.

I am using system.reflection.emit to create a dynamic assembly that will hold mock types which are also dynamically generated.

Everything works fine if I instantiate these types myself through regular object creation with “new”.

The problem is when I try to add a mock of a type that derives from monobehavior using AddComponent I get the following error message:
“The scripts file name does not match the name of the class defined in the script!”

But, there is no file. The class only exists in memory.

Here is an example:
I have a class, MyClass:

public class MyClass : MonoBehavior
{
    int MyModifier = 10;

    virtual public int MyMethod (int MyInt)
    {
        return (MyInt + MyModifier);
    }
}

I have code that I want to unit test which uses this class. I don’t want the code under test to rely on this class so I want to mock the class during test and replace it with this:

public class MockMyClass : MyClass
{
    override public int MyMethod (int MyInt)
    {
        return 0;
    }
}

This mock class is created dynamically in memory at run time (I eventually want to mock every class in our source code and I don’t want to have to maintain that manually).

I am using dependency injection via a generic container and the factory pattern. So, when the code under test wants to get an object of MyClass it calls the factory which will actually return an object of type MockMyClass if a test flag is true.

Like I said, this works fine for objects instantiated via “new”. But when trying to use AddComponent I get the problem described above.

The mock of a type that derives from monobehavior, must be a class, which must be on its own file named as you named the class.

For instance, lets say you define a mockup named Mooky.

It would be defined like this:

public class Mooky : Monobehavior
{
}

And will reside within a file named Mooky.cs

Now you can AddComponent (or drag the Mooky.cs script).

Is the emitted type in a namespace? Unity gives the same error if you try to define a MonoBehaviour in a namespace.

You might be interested in our approach to a unit testing framework for Unity - see this post

It’s a rather different approach, designed to cut out Unity entirely and yield Plain Old C Sharp code.