如何在Windows窗体代码后面编写方法的单元测试 [英] How to write unit test for method in back of windows form code

查看:87
本文介绍了如何在Windows窗体代码后面编写方法的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有要测试的方法,并且收到此错误在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke".现在,我还有一个列表框,该列表框正在我正在测试的函数中填充.因此,当我将Method分离到另一个类时,这是一个问题.

I have method I want to test and I get this error "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." Now I also have a list box that is being populated inside that function I am testing. So its an issue when I separate the Method to another class.

我理解这一点,因为表单需要首先运行,但是还有其他选择吗?

I understand this because of the form needs to run first, but any alternatives?

public partial class ImportForm : Form
{
    public ImportForm()
    {
    }
    public bool Test(string[] fileNames)//Method to test
    {
        foreach (DataTable table in result.Tables)
        {
            foreach (DataRow dr in table.Rows)
            {
                if (!db.CouncilRefundCases.Any(
                        c => c.RequestReference == dr.ItemArray[1].ToString()))
                {
                    CouncilRefundCase data = new CouncilRefundCase()
                    {
                        FileId = fileId,
                        RequestReference = Convert.ToString(dr.ItemArray[1]),
                        CancelReason = Convert.ToString(dr.ItemArray[2]),
                        ProcessStatusId = (int?)ProcessStatus.Unprocessed,
                        ProcessDescription = new EnumHelper().GetDescription(ProcessStatus.Unprocessed),
                        DateCaptured = DateTime.Now
                    };

                    db.CouncilRefundCases.InsertOnSubmit(data);

                    //Succeeded ones
                    var item = new ListViewItem(dr.ItemArray[1].ToString());
                    lstSuccessSummary.Invoke((Action)delegate
                    {
                        lstSuccessSummary.Items.Add(item);
                    });
                }
                else
                {
                    //Failed ones
                    var item = new ListViewItem(dr.ItemArray[1].ToString());
                    lstSummary.Invoke((Action)delegate
                    {
                        lstSummary.Items.Add(item);
                    });
                }
            }
        }
        return true;
    }
}

这是我的单元测试

[TestMethod]
public void TestTest()
{
    bool results=false;
    var files = new string[4];
    files[0] = @"filename1.xlsx";
    files[1] = @"filename2.xlsx";

    ImportForm form= new ImportForm();
     results = form.Test(files);

    Assert.AreEqual(true, results);
}

推荐答案

注意-阅读答案之前

通常,紧紧耦合UI代码和业务逻辑不是一个好主意,但是如果您遇到无法重构为与UI分离的代码,则可以使用以下解决方案来解决问题.

In general it's not good idea to couple UI code and business logic tightly, but in case which you are faced with a code which cannot be refactored to be decoupled from UI, you can use the following solution to solve the problem.

问题与解决方案

在显示表单之前,表单及其控件不在

Before showing the form, the form and its controls are not in Created state and you can not use Invoke method of the form or its controls.

要解决此问题,您可以强制创建表单及其控件.为此,只需调用内部

To solve the problem, you can force the form and its controls to be created. To do so, it's enough to call internal CreateControl(bool fIgnoreVisible) method of your form and pass true to it as parameter:

var f = new Form1();
var createControl = f.GetType().GetMethod("CreateControl",
    BindingFlags.Instance | BindingFlags.NonPublic);
createControl.Invoke(f, new object[] { true });

替代解决方案

  • 在调用方法之前显示Form.然后,表格将在运行单元测试期间显示.

  • Showing the Form before calling the method. Then the form will be shown during running unit tests.

STA线程中显示Form.

示例

假设您的表单中有这样的方法:

Let's say you have such method in your form:

public partial class Form1 : Form
{
    //...
    public int Method1(int i)
    {
        this.Invoke(new Action(() => { i++; }));
        return i;
    }
}

然后在测试项目中,可以使用以下代码:

Then in your test project, you can use the following code:

[TestMethod]
public void TestMethod1()
{
    var f = new Form1();

    var createControl = f.GetType().GetMethod("CreateControl",
        BindingFlags.Instance | BindingFlags.NonPublic);
    createControl.Invoke(f, new object[] { true });

    var input = 0;
    var expected = 1;
    var actual = f.Method1(input);
    Assert.AreEqual(expected, actual);
}

这篇关于如何在Windows窗体代码后面编写方法的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆