10

基本上,我的一些测试是成功的,有些是失败的。根据 Skeet 先生的极好建议,我创建了一个完整的代码示例以确认我没有发疯。这是代码:

namespace ClassLibrary
{
    using System;

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

我的测试是:

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);
        }
    }
}

第一个测试 (TestPasses()) 有效。

第二个测试 (TestErrorsOut()) 失败并出现以下错误:{"Method 'ClassLibrary.Manager.SampleMethod' not found."}

令人费解的是错误是一致的,但实际测试几乎相同。这没有道理。我在 VS2012 RC 和 VS2010 上试过这个,结果相同。

我唯一能想到的是“0”被转换为除int之外的东西,这意味着它找不到SampleMethod的方法签名?我尝试了第三个测试来显式传递我正在寻找的类型 (TestAlsoErrorsOut()),但这也会出现同样的错误。

想法?谢谢。

编辑以添加

通过使用 Ian 的建议,即使用 obj[] 而不是 params obj[] 重载,它可以工作(测试 TestWorksAsWell())。这就解释了为什么 TestAlsoErrorsOut() 会失败,因为我使用的是 params 方法,该方法不适用于 Type[]。所以,这是固定的。但为什么?为什么 params obj[] 在传递 1 而不是 0 时会起作用?

4

3 回答 3

13

根据文档(http://msdn.microsoft.com/en-us/library/ms243710.aspx),参数应该作为对象数组传递。显式传递对象数组似乎可以正常工作:

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

自行传递 0 似乎会导致编译器选择此重载

Invoke(string name = "SampleMethod", System.Reflection.BindingFlags bindingFlags = Default, object[] args = {object[0]})
于 2012-07-25T11:40:51.200 回答
1

调用以下测试时,我得到了 System.MissingMethodException:

PrivateObject shadow = new PrivateObject(target);    
shadow.Invoke("PrivateMethod", new string[]{"arg1","arg2"});

关于目标的私有方法签名

private void PrivateMethod(string[] args)

我必须在私有方法签名中添加参数来解决异常,如下所示:

private void PrivateMethod(params string[] args)
于 2017-02-03T10:39:09.317 回答
1

伊恩·吉尔罗伊(Ian Gilroy)是对的,但原因是;这是因为PrivateObject.Invoke有很多签名,其中之一是:Invoke(string name, Type[] types, object[] objects).

在我的情况下,我传递的值如下:Invoke("MethodName", null, null),在这种情况下,C# 编译器更喜欢提到的签名,而不是Invoke(string name, params object[] objects),这会导致错误。

于 2019-03-04T07:54:14.157 回答