模拟Gtk#控件进行单元测试

时间:2016-10-18 16:57:40

标签: c# unit-testing mono moq gtk#

修改:Fixed the problem

我的问题(TL; DR)

我正在尝试测试我的Gtk#控件包装器实现,但是当我尝试使用模拟Gtk.Button作为参数创建我的对象时,我得到了一个

System.MissingMethodException : Method 'MyNameSpace.GUI.GTKSharp.GtkSharpButton..ctor' not found.
    at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
    at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00038] in /build/mono/src/mono-4.6.1/mcs/class/corlib/System.Reflection/MonoMethod.cs:305 

测试代码:

[TestFixture]
public class GtkSharpButtonTests
{
    private Mock<Gtk.Button> _buttonMock;

    [TestFixtureSetUp]
    public void BeforeAllSetUp()
    {
        _buttonMock = new Mock<Gtk.Button>();
    }

    [Test]
    public void My_Test()
    {
        var called = false;            
        // ---> System.MissingMethodException
        var button = new GtkSharpButton(_buttonMock.Object);

        // .... rest of the test           
    }
}

我的猜测是,当它尝试创建GtkSharpButton(我的实现)时,它使用Castle proxy object创建它,但它找不到期望此类型的GtkSharpButton构造函数。

模拟一个具体的类也可能是一个问题,也许我做错了。

我使用相同的技术测试了其他图层,但其他图层依赖于界面,因此更容易模拟。

使用的套餐:

  • Moq v4.5.23
  • NUnit v2.6.4
  • Castle.Core v3.3.3
  • gtk-sharp v3.0.0(来自gtk-sharp-3.0 v2.99.3
  • glib-sharp v3.0.0(来自gtk-sharp-3.0 v2.99.3
  • atk-sharp v3.0.0(来自gtk-sharp-3.0 v2.99.3

我使用mono v4.6.1.3中的Monodevelop v5.10.1在Linux上。但这也发生在nunit-console v2.4.8

有关我正在做什么的更多信息

我目前正在创建一个C#应用,我想抽象出View图层。

要在创建Controller时执行此操作,我会传递一个视图界面(例如IMainWindowView)。

这样我可以混合搭配不同的实现:

IMainWindowView view = new GtkSharpMainWindowView();
IMainWindowView view = new WPFMainWindowView();

var mainWindowController = new MainWindowController(view);

IMainWindowView示例:

public interface IMainWindowView
{
    IButton ExampleButtonName { get; }

    IButton ExampleButtonName2 { get; }

    // ....
}

这些

背后的代码

接口:

public interface IControl
{
    string Tooltip { get; set; }
}

public interface IButton : IControl
{
    event ButtonClickEventHandler Triggered;

    void Trigger();
}

包装器实现:

public abstract class GtkSharpControl : IControl
{
    protected Widget BaseWidget { get; private set; }

    public string Tooltip
    {
        get { return BaseWidget.TooltipText; }
        set { BaseWidget.TooltipText = value; }
    }

    protected GtkSharpControl(Widget widget)
    {
        if (widget == null)
            throw new ArgumentNullException(nameof(widget));

        BaseWidget = widget;
    }
}

public class GtkSharpButton : GtkSharpControl, IButton
{
    public event ButtonClickEventHandler Triggered;

    protected Button BaseWidget
    {
        get { return base.BaseWidget as Button; }
    }

    public GtkSharpButton(Button button)
        : base(button)
    {
        BaseWidget.Clicked += Button_Clicked;
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        if (Triggered != null)
            Triggered(this, new ButtonEventArgs());
    }

    public void Trigger()
    {
        BaseWidget.Click();
    }
}

此实现目前运行良好,但我目前无法测试GtkSharp控件实现层。

如果您需要更多信息,请询问。

1 个答案:

答案 0 :(得分:1)

我解决了我的问题。

这只是使用不同库版本的问题。我没有在我的测试和实现中使用相同的gtk-sharp库版本。

Code项目正在使用gtk-sharp2(v2.12.29)

测试项目正在使用gtk-sharp3(v2.99.3)

所以当它创建一个模拟时,它创建了一个gtk-sharp3按钮模拟,但是我的类构造函数期望一个gtk-sharp2按钮,所以它失败了。

感谢knocte for helping me figure it out询问我如何安装gtk-sharp lib。