Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating instance of class accessor

I am currently writing a unit test framework which shall in the end run standard unit tests written in Visual Studio. The Framework is currently not working correctly with accessors. Consider the following test method:

[TestMethod()]
public void TestMethod()
{
      ExampleMethods_Accessor target = null;
      target = new ExampleMethods_Accessor();
      target.SomeMethod();
}

In this example, the accessor has been generated by Visual Studio. The unit test works perfectly fine when run using the Unit Testing environment of Visual Studio. However, I would like to invoke the TestMethod() from within my Framework. At the line "target = new ExampleMethods_Accessor()", the following exception is thrown:

The type initializer for "Proband.ExampleMethods_Accessor" threw an excepition.

Inner exception:

Could not load file or assembly: Proband, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null...

Has anyone an idea of how the Microsoft Unit Testing Framework invokes unit tests? I was thinking it might be due to the missing TestContext object. This is "null" in my case. When starting the unit test in Visual Studio, the TestContext object contains a lot of information. Could it be, that I need to initialize it properly? How would it need to be initialized?

Thanks for all help, Christian

EDIT:

I kept experimenting with the way accessors are working. I used ILSpy to see what code is being generated into the Proband_Accessor.dll. It turns out that the instruction causing the exception is:

SomeClass_Accessor.m_privateType = new PrivateType("Probant, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Probant.SomeClass");

I modified my unit test code to be like this (just for test):

    [TestMethod()]
    [DeploymentItem("Proband.dll")]
    public void SomeMethodTest()
    {
        ExampleMethods_Accessor target = null;
        ExampleMethods c = null;

        try
        {
            Assembly.Load("Proband, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); // this works fine
            PrivateType tx = new PrivateType(typeof(ExampleMethods)); // this works fine as well (also without loading the assembly)

            PrivateType t = new PrivateType("Proband, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Proband.ExampleMethods"); // this causes the exception

            c = new ExampleMethods(); // this works fine
            target = new ExampleMethods_Accessor(); // this causes the exception as well
        }
        catch (Exception ex)
        {
            Console.WriteLine();
        }
        int actual;
        actual = target.SomeMethod();
    }

I do absolutely not understand, why "new PrivateType("Proband, Version...." does not work. Has anyone an idea?

like image 501
Christian Avatar asked Nov 13 '22 16:11

Christian


1 Answers

I have managed to create a workaround for the issue.

To my AppDomain, I am adding an AssemblyResolveEventHandler:

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

This event handler contains the following code:

    private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
    {
        if(args.Name == "Proband, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
        {
            // resolving correct assembly of type under test
            return typeof(ExampleMethods).Assembly;
        }
        else
        {
            return null;
        }
    }

Now the line of code "target = new ExampleMethods_Accessor();" works fine and returns the correct accessor object.

I still do not understand, why the Assembly cannot be resolved automatically.

Even if it is very unlikely that anyone will have the same problem: I hope this answer helps someone :)

like image 191
Christian Avatar answered Dec 19 '22 17:12

Christian