我有依赖,我想嘲笑。
public abstract class MyDependency
{
protected Dictionary<string, object> _outputs = new Dictionary<string, object>();
public Dictionary<string, object> Outputs
{
get
{
return _outputs;
}
}
}
我需要公共属性Outputs
来返回已知值,以便进行单元测试。我知道我们不能模拟字段或非虚拟成员。所以,我可以创建自己的模拟MyDependency
来设置支持字段_outputs
:
public class MockMyDependency : MyDependency
{
public MockMyDependency()
{
_outputs = new Dictionary<string, object>
{
{ "key", "value" }
};
}
}
但是,是否可以使用Moq来实现这一点而无需显式创建我自己的派生模拟类?
答案 0 :(得分:4)
如果您不能将属性更改为虚拟或定义接口(我假设如果您不能执行第一个属性,则无法执行第二个属性),那么我只看到两个可能的选项:< / p>
答案 1 :(得分:2)
如果你不是自己派生出来的,那么很难指定protected
字段_outputs
,因为它不在范围内,其名称也不会编译。
但你当然可以用讨厌的反思来做到这一点:
var mock = new Mock<MyDependency>();
var field = typeof(MyDependency)
.GetField("_outputs", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(mock.Object,
new Dictionary<string, object> { { "key", "value" } });
如果你做毕竟从MyDependency
派生,那么在从它派生的类中,你可以直接设置字段,如:
// this code is inside some class which derives from MyDependency
mock.Object._outputs = new Dictionary<string, object> { { "key", "value" } };
答案 2 :(得分:1)
我想我明白你在问什么,我想你正在寻找这样的事情:
public class Test
{
public void MockObject()
{
var mocked = new Moq.Mock<MyDependency>();
mocked.CallBase = true;
mocked.Setup(m => m.Outputs).Returns(new Dictionary<string, object>() { { "key", "value" } });
mocked.Object.{do something with mocked object};
}
}
...我认为你仍然需要在virtual
财产上Outputs
。
答案 3 :(得分:1)
声明一个从MyDependency类公开所需成员的接口,然后可以将其与Moq一起使用来创建测试所需的行为。
public interface IMyDependency {
Dictionary<string, object> Outputs { get; }
}
// test...
var dictionary = new Dictionary<string, string>{{"key", "value"}};
var dependency = new Mock<IMyDependency>();
dependency.SetupGet(d => d.Outputs).Returns(dictionary);
当您在生产代码中使用它时,您可以使用DuckTyping(或类似)在您的界面后面“强制转换”MyDependency实例。