Как написать модульный тест для метода в задней части окна формы кода - PullRequest
0 голосов
/ 05 июня 2018

У меня есть метод, который я хочу проверить, и я получаю эту ошибку «Invoke или BeginInvoke не могут быть вызваны для элемента управления, пока не будет создан дескриптор окна».Теперь у меня также есть список, который заполняется внутри функции, которую я тестирую.Так что это проблема, когда я отделяю Метод от другого класса.

Я понимаю это, потому что сначала нужно запустить форму, но есть ли альтернативы?

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);
}

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Примечание. Перед прочтением ответа

В общем случае не стоит тесно связывать код пользовательского интерфейса и бизнес-логику, но в случае, если вы столкнулись с кодом, который не может бытьРеорганизованный для отделения от пользовательского интерфейса, вы можете использовать следующее решение для решения проблемы:

Проблема и решение

Перед показом формы, формы и ееэлементы управления не находятся в состоянии Created, и вы не можете использовать метод Invoke формы или ее элементов управления.

Чтобы решить проблему, вы можете принудительно создать форму и ее элементы управления.Для этого достаточно вызвать внутренний CreateControl(bool fIgnoreVisible) метод вашей формы и передать true в качестве параметра:

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

Альтернативные решения

  • Отображение Form перед вызовом метода.Затем форма будет отображаться во время выполнения модульных тестов.

  • с указанием Form в потоке STA.

Пример

Допустим, у вас есть такой метод в вашей форме:

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

Затем в своем тестовом проекте вы можете использовать следующий код:

[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);
}
0 голосов
/ 05 июня 2018

Трудно сказать без реального кода, но обычно это указывает на то, что код в методе Test не должен быть в Форме.

Формы должны действительно быть логикой отображения, а не логикой модели.

Теперь у меня также есть список, который заполняется внутри функции, которую я тестирую.Поэтому проблема заключается в том, что я разделяю метод на другой класс.

Если вы опишите проблему с каким-то кодом, мы сможем помочь с этим.Вы можете решить ее с помощью событий или делегатов, чтобы исключить логику представления из вашей модели, и наоборот.

...