单元测试WinForms中动态填充的用户控件

时间:2016-11-01 11:58:34

标签: c# winforms unit-testing moq mvp

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

我认为在用户控件方面我遇到了问题,我在单元测试中发现了这个问题

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

我想对这个类中的逻辑进行单元测试,因为这是我认为最重要的测试。我只是不知道如何做到这一点,因为这个类中有逻辑和表单控件。我目前正在使用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();
    }
}

其他用户控制功能('答案'是控件列表)

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

1 个答案:

答案 0 :(得分:0)

  

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

因此将它们分成不同的类并测试仅包含逻辑

的类