基本上,我的一些测试成功,有些失败。根据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())失败,出现以下错误: {“找不到方法'ClassLibrary.Manager.SampleMethod'。”}
令人困惑的是错误是一致的,但实际测试几乎完全相同。这没有道理。我在VS2012 RC和VS2010上尝试了这个,结果相同。
我唯一能想到的是“0”会被转换成除了int之外的东西,这意味着它找不到SampleMethod的方法签名?我尝试了第三个测试,以显式传递我正在寻找的类型(TestAlsoErrorsOut()),但这也错误输出相同的错误。
想法?谢谢。
编辑以添加
通过使用Ian的建议使用obj []而不是params obj []重载,它可以工作(测试TestWorksAsWell())。这就解释了为什么TestAlsoErrorsOut()失败,因为我使用的是params方法,它不适用于Type []。所以,这是固定的。但为什么?为什么params obj []在传递1时工作,而不是0?
答案 0 :(得分:12)
根据文档(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]})
答案 1 :(得分:1)
调用以下测试时,我收到了System.MissingMethodException:
PrivateObject shadow = new PrivateObject(target);
shadow.Invoke("PrivateMethod", new string[]{"arg1","arg2"});
在目标的私有方法签名
上private void PrivateMethod(string[] args)
我必须在私有方法签名中添加params以解决异常,如下所示:
private void PrivateMethod(params string[] args)
答案 2 :(得分:0)
PrivateObject.Invoke
有很多签名,其中之一是:Invoke(string name, Type[] types, object[] objects)
。
在我的情况下,我传递的值类似:Invoke("MethodName", null, null)
,在这种情况下,C#编译器比Invoke(string name, params object[] objects)
更喜欢提到的签名,这会导致错误。