在WinForms中对动态填充的用户控件进行单元测试

本文关键字:控件 用户 单元测试 填充 WinForms 动态 | 更新日期: 2023-09-27 18:15:50

我有一个实现MVP模式(被动视图)的WinForms项目。

我认为当涉及到用户控件时,我对模式有一个问题,这是我在单元测试中发现的

我有一个用户控件,作为在我的视图中触发的事件的结果,我把它放在我的表单上。该用户控件根据从视图获得的数字向自身添加一定数量的标签、文本框等。最后,它告诉视图将用户控件添加到视图中。

我想对这个类中的逻辑进行单元测试,因为我认为这是最重要的测试。我只是不知道如何做到这一点,因为在这个类中既有逻辑和形式控件。我目前使用Moq来创建我的单元测试。

我通常会创建一个Mock对象来表示视图,然后单独测试要测试的对象中方法的实现。然而,因为我在这个类中创建控件,我不认为我可以这样测试(不包括. forms库)。

我希望有人知道解决办法。

编辑:我一直试图将我的逻辑从控制操作中分离出来,但我正在努力解决我在原始用户控制代码下面发布的不同用户控制的功能。由于我循环遍历一个控件列表,我不知道如何将其分为逻辑和控件处理。

用户控制码

public partial class DetailScreenUserControl : UserControl
{
    // Private members.
    private readonly IDetailScreenView _view;
    private List<ComboBox> maturityInput = new List<ComboBox>();
    private List<ComboBox> complianceInput = new List<ComboBox>();
    // Public members.
    public List<string> MaturityInput
    {
        get
        {
            var list = new List<string>();
            for (int i = 0; i < maturityInput.Count; i++)
            {
                list.Add(maturityInput[i].Text);
            }
            return list;
        }
        set
        {
            for (int i = 0; i < maturityInput.Count; i++)
            {
                maturityInput[i].DataSource = new List<string>(value);
            }
        }
    }
    public List<string> ComplianceInput
    {
        get
        {
            var list = new List<string>();
            for (int i = 0; i < complianceInput.Count; i++)
            {
                list.Add(complianceInput[i].Text);
            }
            return list;
        }
        set
        {
            for (int i = 0; i < complianceInput.Count; i++)
            {
                complianceInput[i].DataSource = new List<string>(value);
            }
        }
    }
    // Initialize user control with IDetailScreenView. Subscribe to necessary events.
    public DetailScreenUserControl(IDetailScreenView view)
    {
        InitializeComponent();
        _view = view;
        _view.InitializingUserControl += InitializeUserControl;
    }
    // Initializes the user control for the detail screen.
    public void InitializeUserControl(object sender, EventArgs e)
    {
        List<string> qStandards = _view.SelectedQuestionStandards;
        Controls.Clear();
        maturityInput.Clear();
        complianceInput.Clear();
        int inputSeparation = Height / 2;
        int spacing = Width / 20;
        Size = new Size(_view.RightUserControlBoundary - Location.X, Size.Height);
        for (int  i = 0; i < qStandards.Count; i++)
        {
            Panel inputPanel = new Panel();
            inputPanel.BackColor = Color.AliceBlue;
            inputPanel.Location = new Point(0, i * inputSeparation);
            inputPanel.Size = new Size(Width - spacing, inputSeparation);
            Controls.Add(inputPanel);
            Label qs_label = new Label();
            qs_label.AutoSize = true;
            qs_label.Location = new Point(0, 0);
            qs_label.Font = new Font("Arial", 12F, FontStyle.Bold);
            qs_label.AutoSize = true;
            qs_label.Text = qStandards[i].ToString();
            inputPanel.Controls.Add(qs_label);
            Label m_label = new Label();
            m_label.AutoSize = true;
            m_label.Location = new Point(0, qs_label.Bounds.Bottom + qs_label.Height / 2);
            m_label.Font = new Font("Arial", 12F, FontStyle.Regular);
            m_label.Text = "Maturity standard";
            inputPanel.Controls.Add(m_label);
            Label c_label = new Label();
            c_label.AutoSize = true;
            c_label.Location = new Point(0, m_label.Bounds.Bottom + qs_label.Height / 2);
            c_label.Font = new Font("Arial", 12F, FontStyle.Regular);
            c_label.Text = "Compliance standard";
            inputPanel.Controls.Add(c_label);
            ComboBox m_input = new ComboBox();
            m_input.AutoSize = true;
            m_input.Location = new Point(c_label.Bounds.Right + 2 * spacing, m_label.Bounds.Top);
            m_input.Font = new Font("Arial", 10F, FontStyle.Regular);
            m_input.DropDownStyle = ComboBoxStyle.DropDownList;
            m_input.Size = new Size(inputPanel.Size.Width - m_input.Bounds.Left, spacing);
            maturityInput.Add(m_input);
            inputPanel.Controls.Add(m_input);
            ComboBox c_input = new ComboBox();
            c_input.AutoSize = true;
            c_input.Location = new Point(c_label.Bounds.Right + 2 * spacing, c_label.Bounds.Top);
            c_input.Font = new Font("Arial", 10F, FontStyle.Regular);
            c_input.DropDownStyle = ComboBoxStyle.DropDownList;
            c_input.Size = new Size(inputPanel.Size.Width - c_input.Bounds.Left, spacing);
            complianceInput.Add(c_input);
            inputPanel.Controls.Add(c_input);
        }
        if(qStandards.Count != 0)
        {
            saveAssessmentButton.BackColor = System.Drawing.SystemColors.ButtonHighlight;
            Controls.Add(saveAssessmentButton);
            saveAssessmentButton.Location = new Point(this.Size.Width - saveAssessmentButton.Width - spacing, qStandards.Count * inputSeparation);
        }
        _view.AddUserControl();
    }
    // Tells the view to save the assessment.
    private void saveAssessmentButton_Click(object sender, EventArgs e)
    {
        _view.SaveAssessmentButtonClicked();
    }
}

其他用户控件功能('answers'是控件列表)

public void SaveResults()
{
    results = new List<string>();
    int questionNr = 0;
    for (int p = 0; p < questions.Count; p++)
    {
        for (int i = 0; i < questions[p].Count; i++)
        {
            bool unanswered = true;
            results.Add(questions[p][i]);
            for (int j = 1; j <= maturityAnswers[p].Count; j++)
            {
                var radioButton = (RadioButton)answers[questionNr][j];
                if (radioButton.Checked)
                {
                    results.Add(answers[questionNr][j].Text);
                    unanswered = false;
                }
            }
            if (unanswered == true)
            {
                results.Add("");
            }
            unanswered = true;
            for (int j = maturityAnswers[p].Count + 1; j <= (maturityAnswers[p].Count + complianceAnswers[p].Count); j++)
            {
                var radioButton = (RadioButton)answers[questionNr][j];
                if (radioButton.Checked)
                {
                    results.Add(answers[questionNr][j].Text);
                    unanswered = false;
                }
            }
            if (unanswered == true)
            {
                results.Add("");
            }
            results.Add(answers[questionNr][0].Text.Replace("'", "''"));
            questionNr++;
        }
    }

在WinForms中对动态填充的用户控件进行单元测试

我想对这个类中的逻辑进行单元测试,因为这就是我要做的思考是最重要的测试。我只是不知道该怎么做,因为在这个类中有逻辑和表单控件

那么将它们分离到不同的类并测试只包含逻辑的类