- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试对使用反射构造派生自已知基类的未知对象的工厂类进行单元测试。
但是,当工厂试图调用从我的假单元类型派生的构造函数时,我遇到了一个异常。这是一个空引用异常。
我正在使用 FakeItEasy。这是我在这里进行的操作:
[TestFixture]
public class DisplayUnitFactoryTests
{
private readonly IDisplayUnitPluginContainer _mgr = A.Fake<IDisplayUnitPluginContainer>();
private readonly DisplayUnitPlugin _plgin = A.Fake<DisplayUnitPlugin> ();
private DisplayUnit _unit;
private Guid _guid;
[TestFixtureSetUp]
public void init()
{
_unit = A.Fake<DisplayUnit> (p=> p.WithArgumentsForConstructor(new object[]{new Dictionary<string,string>()}));
_guid = Guid.NewGuid ();
A.CallTo (() => _mgr.Resolve (VALID_STRING)).Returns (_plgin);
A.CallTo (() => _mgr.Resolve (INVALID_STRING)).Returns (null);
A.CallTo (() => _plgin.DisplayUnitType).Returns (_unit.GetType ());
}
底线是我的问题。 DisplayUnit 是一个抽象类。在这种情况下,它的实现应该无关紧要,除了它的构造函数。但是,DisplayUnit 有一个需要字典作为参数的构造函数。
如果我使用 REAL 类型(不是伪造的),代码工作正常。(例如 A.CallTo(() => _plgin.DisplayUnitType).Returns(typeof(TextUnit) );
但是,该真实类型需要我的核心代码之外的依赖项。我希望在运行时将不同类型的 DisplayUnit 作为插件添加。因此,我想使用假显示单元对我的 DisplayUnitFactory 进行单元测试. 在这个测试中,我不需要依赖外部程序集来完成这项工作。
这是我的测试。
[Test]
public void InstantiateNew_ValidPluginID_EmptyDict_ReturnsCorrectDisplayUnit()
{
var factory = new DisplayUnitFactory (_mgr);
var du = factory.InstantiateNew (VALID_STRING, new Dictionary<string, string> ());
Assert.That (du, Is.Not.Null);
}
这是我的工厂代码:
public DisplayUnit InstantiateNew (string pluginId, Dictionary<string, string> attributes)
{
return getDisplayUnit (pluginId, attributes);
}
private DisplayUnit getDisplayUnit(string pluginId, Dictionary<string,string> attributes)
{
//Get the constructor that accepts only a dictionary<string,string>.
var ctor = getCtor (pluginId, new Type[]{typeof(Dictionary<string,string>)});
//Invoke it with the attributes dictionary.
var unit = ctor.Invoke (new object[]{ attributes }) as DisplayUnit;
return unit;
}
private ConstructorInfo getCtor(string pluginId, Type[] paramTypes)
{
var plugin = _container.Resolve (pluginId);
if (plugin == null)
throw new NotRegisteredPluginException ("Plugin not registered: " + pluginId);
var type = plugin.DisplayUnitType;
return type.GetConstructor (paramTypes);
}
本质上,我需要伪造将使用反射产生的 ConstructorInfo,并最终伪造 ConstructorInfo.Invoke() 的返回值。但是当调用构造函数时,我在 getDisplayUnit()
中得到一个空引用异常,因为 ctor
返回 null。
帮助!
最佳答案
所以感谢 Blair,我相信我已经找到了解决方案:根本不使用假的。
伪造的类型将只有一个带有参数的公共(public)构造函数 Castle.DynamicProxy.IInterceptor[], Dictionary<System.String,System.String>
.因此,当 Reflection 试图获取构造函数时,整个过程就崩溃了。
解决方案是创建一个 DummyDisplayUnit
源自 DisplayUnit
并改用它。这工作得很好,不需要假货。
我想有时我会尝试抽象到错过明显解决方案的地步......
关于c# - 当您正在测试的类在 C# 中使用反射时如何使用假货进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37468643/
我最近一直在与 Moles 合作,现在我正在转向 Fakes。在我的旧测试项目中,我有一个测试设置,如下所示: [TestInitialize] public void Setup() { /
我正在为一个项目的客户工作,现有的代码/测试正在使用 MS Fakes 库和 Shims 来隔离测试等... 我在试用中安装了 VS 2015 企业版,一切都很好。通过我的 MSDN 订阅,我升级到
我是一名优秀的程序员,十分优秀!