我正在尝试在模拟对象上测试私有方法。请冷静下来,我知道你要把你的干草叉拿出来。
我很清楚所有要说的话都可以通过向我大喊大叫REFACTOR来回答。我只需要一个直接的答案。有人看着我的眼睛,告诉我这是不可能完成的。这是一个不可解决的问题,所以我只需要听一听。
这就是我正在处理的事情。
public class SecretManager
{
protected virtual string AwfulString { get { return "AWFUL, AWFUL THING"; }
public SecretManager()
{
//do something awful that should be done using injection
}
private string RevealSecretMessage()
{
return "don't forget to drink your ovaltine";
}
}
这是我试图测试它。
var mgr = new Mock<SecretManager>();
mgr.Protected().SetupGet<string>("AwfulThing").Returns("");
var privateObj = new PrivateObject(mgr.Object);
string secretmsg = privateObj.Invoke("RevealSecretMessage");
Assert.IsTrue(secretmsg.Contains("ovaltine"));
和例外:
System.MissingMethodException: Method 'Castle.Proxies.SecretManagerProxy.RevealSecretMessage' not found
我正在尝试做什么,可能是疯了吗?或者这对单元测试来说太过狂妄了?
答案 0 :(得分:3)
您正尝试在Castle创建的代理上调用方法。代理将无法访问它继承的类的私有方法,因为该方法是私有的。请记住,Castle.Proxies.SecretManagerProxy实际上是SecretManager的子类。
你真的需要一个模拟SecretManager吗?我意识到你的代码是真实代码的简洁摘要,但是你似乎唯一能做的就是设置一个属性的返回值,这个属性不是你试图测试的方法所使用的
答案 1 :(得分:1)
您的代码应该遵循您要测试的内容。您不需要模拟SecretManager和SetGet“AwfulThing”,因为您没有使用它。
var privateObj = new PrivateObject(new SecretManager());
string secretmsg = (string)privateObj.Invoke("RevealSecretMessage", new object[] { });
Assert.IsTrue(secretmsg.Contains("ovaltine"));
但理想情况下,您不应该测试私有方法。请参阅以下文章以获得解释:
http://lassekoskela.com/thoughts/24/test-everything-but-not-private-methods/
答案 2 :(得分:1)
var privateObj = new PrivateObject(mgr.Object, new PrivateType(typeof(SecretManager)));
string secretmsg = privateObj.Invoke("RevealSecretMessage");
它可以为PrivateType
指定PrivateObject
。