Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running into System.MissingMethodException: Method Not Found with PrivateObject

Basically, some of my tests are succeeding, some are failing. Per Mr. Skeet's excellent suggestion, I created a full code sample to confirm I'm not crazy. This is the code:

namespace ClassLibrary
{
    using System;

    public class Manager
    {
        private int SampleMethod(int id)
        {
            return id;
        }
    }
}

My test is:

namespace UnitTestProject
{
    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTest
    {
        [TestMethod]
        public void TestPasses()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var actual = privateInfo.Invoke("SampleMethod", 1);
        }

        [TestMethod]
        public void TestErrorsOut()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var actual = privateInfo.Invoke("SampleMethod", 0);
        }

        [TestMethod]
        public void TestWorksAsWell()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            privateInfo.Invoke("SampleMethod", new object[] { 0 });
        }

        [TestMethod]
        public void TestAlsoErrorsOut()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var types = new Type[] { typeof(int) };
            var actual = privateInfo.Invoke("SampleMethod", types, 0);
        }
    }
}

The first test (TestPasses()) works.

The second test (TestErrorsOut()) fails with the following error: {"Method 'ClassLibrary.Manager.SampleMethod' not found."}

The baffling thing is the error is consistent, but the actual test is almost identical. It makes no sense. I tried this on VS2012 RC and VS2010, with the same results.

The only thing I can think of is "0" is getting cast as something besides int, which means it can't find the method signature of SampleMethod? I tried a third test to explicitly pass in the type I'm looking for (TestAlsoErrorsOut()), but that also errors out with the same error.

Ideas? Thanks.

Edit to add

By using Ian's suggestion of using the obj[] instead of params obj[] overload, it works (test TestWorksAsWell()). And that explains why TestAlsoErrorsOut() fails, because I'm using params method, which wouldn't work with Type[]. So, this is fixed. But, why? Why will params obj[] work when passing a 1, but not a 0?

like image 975
bryanjonker Avatar asked Jul 24 '12 23:07

bryanjonker


People also ask

How do I fix MissingMethodException?

To fix the Method not found error in C#, ensure that the latest assemblies are deployed and no duplicate or older assemblies are existing in any of the sub folders with-in your application.

What is missing method exception?

MissingMethodException is designed to handle cases where an attempt is made to dynamically access a renamed or deleted method of an assembly that is not referenced by its strong name. MissingMethodException is thrown when code in a dependent assembly attempts to access a missing method in an assembly that was modified.


2 Answers

According to the docs (http://msdn.microsoft.com/en-us/library/ms243710.aspx) the arguments are supposed to be passed as an array of objects. Explicitly passing an object array appears to work correctly:

var actual = (int)privateInfo.Invoke("SampleMethod", new object[] {0});

Passing 0 on its own appears to result in the compiler selecting this overload

Invoke(string name = "SampleMethod", System.Reflection.BindingFlags bindingFlags = Default, object[] args = {object[0]})
like image 146
Ian Gilroy Avatar answered Sep 30 '22 12:09

Ian Gilroy


Ian Gilroy is right, but the reason why; it is because PrivateObject.Invoke has many signatures, and one of them is: Invoke(string name, Type[] types, object[] objects).

And in my case, I was passing values like: Invoke("MethodName", null, null), in which case C# compiler prefers the mentioned signature, than Invoke(string name, params object[] objects), which results in error.

like image 32
Ghasan غسان Avatar answered Sep 30 '22 11:09

Ghasan غسان