使用FakeItEasy和xBehave.net,我试图模拟System.Windows.Forms.TreeView。
我收到以下错误:
FakeItEasy.Core.FakeCreationException : Failed to create fake of type "System.Windows.Forms.TreeView".
Below is a list of reasons for failure per attempted constructor:
No constructor arguments failed:
No usable default constructor was found on the type System.Windows.Forms.TreeView.
An exception was caught during this call. Its message was:
Exception has been thrown by the target of an invocation.
这使我感到困惑,因为文档中唯一的constructor I see是公共的默认构造函数。
这是给出错误的演示代码:
using System.Windows.Forms;
using Xbehave;
using FakeItEasy;
namespace MockingTreeView
{
public class Class1
{
TreeView treeView;
[Scenario]
public void MockingTreeView()
{
"Given there is a treeView".f(() =>
{
// Apparently UIPermissionAttribute can't be mocked by this framework
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Security.Permissions.UIPermissionAttribute));
treeView = A.Fake<TreeView>();
});
}
}
}
有谁知道出了什么问题或如何解决这个问题?谢谢。
最佳答案
不幸的是,正在发生的事情是某些类(我以前在WinForms系列中已经注意到这一点)很难伪造。就个人而言,我更愿意在可能的情况下伪造一个定义良好的接口(或很少是一个抽象类)。除了难以获得伪造品之外,有时诸如TreeView
之类的现有类还具有large surface area且复杂的内部行为会让您感到惊讶。
不管怎么说,FakeItEasy有时会尝试提供有用的,友好的错误消息。在这种情况下,有用的本能最终会掩盖正在发生的事情。我们可能应该调查一下。
您对可用构造函数的困惑是可以理解的,但是错误消息中的关键字是可用的。 FakeItEasy找到了默认的构造函数,但由于抛出了异常而无法使用。
我接受了您的测试,并针对FakeItEasy构建进行了测试,可以对它进行调试,并在发现异常时停止。它是一个System.Reflection.TargetInvocationException
,因此并不是特别有用,但是内部异常看起来像:
[System.NullReferenceException]
Message: "Object reference not set to an instance of an object."
StackTrace:
at Castle.Proxies.TreeViewProxy.get_DefaultMargin()
at System.Windows.Forms.Control..ctor(Boolean autoInstallSyncContext)
at System.Windows.Forms.Control..ctor()
at System.Windows.Forms.TreeView..ctor()
at Castle.Proxies.TreeViewProxy..ctor(IInterceptor[] )
这对我说,TreeView的构造函数最终调用
Control
构造函数,该构造函数调用DefaultMargin
的get方面,这是一个受保护的属性。因为它是受保护的,所以FakeItEasy无法看到它,因此在
Control
上调用了原始方法。看起来像这样:/// <include file="doc\Control.uex" path="docs/doc[@for="Control.DefaultMargin"]/*">
protected virtual Padding DefaultMargin {
get { return CommonProperties.DefaultMargin; }
}
(来自Control.cs source code in C# .NET)
我不确定为什么会抛出
NullReferenceException
。因此,这就是(失败的某种方式)失败的原因。
这不是一个令人满意的结论,但是我,我尽量不要伪造TreeView。我会寻找自己拥有和控制的可能伪造的东西,通常是一些易于使用的接口,该接口由使用TreeView的类实现。
关于c# - 在FakeItEasy中 mock TreeView的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25754175/