6

私は現在、Textbox、Groupbox などのフォーム コントロールでいくつかの基本的な操作を行ういくつかのメソッドを作成しています。これらの操作は一般的であり、あらゆるアプリケーションで使用できます。

私はいくつかの単体テストを書き始めましたが、System.Windows.Forms にある実際のフォーム コントロールを使用するべきか、それともテストしようとしているセクションを単にモックアップするべきか疑問に思っていました。たとえば、次のようになります。

コントロールを取るこのメソッドがあり、それがテキストボックスの場合、次のようにテキストプロパティをクリアするとします:

        public static void clearall(this Control control)
        {
            if (control.GetType() == typeof(TextBox))
            {
                ((TextBox)control).Clear();
            }
        }

次に、このメソッドをテストしたいので、次のようにします。

        [TestMethod]
        public void TestClear() 
        {
            List<Control> listofcontrols = new List<Control>();
            TextBox textbox1 = new TextBox() {Text = "Hello World" };
            TextBox textbox2 = new TextBox() { Text = "Hello World" };
            TextBox textbox3 = new TextBox() { Text = "Hello World" };
            TextBox textbox4 = new TextBox() { Text = "Hello World" };

            listofcontrols.Add(textbox1);
            listofcontrols.Add(textbox2);
            listofcontrols.Add(textbox3);
            listofcontrols.Add(textbox4);

            foreach (Control control in listofcontrols)
            {
                control.clearall();
                Assert.AreEqual("", control.Text);
            }
        }

System.Window.Forms への参照を単体テストに追加し、実際の Textbox オブジェクトを使用する必要がありますか? または私はそれを間違っていますか?

注: 上記のコードは単なる例であり、コンパイルも実行もしていません。

4

3 に答える 3

6

UIコントロールとの相互作用をシミュレートしてアプリケーションロジックを単体テストしようとしている場合は、MVCパターンを使用して抽象化を行う必要があります。次に、スタブビューを作成し、単体テストからコントローラーメソッドを呼び出すことができます。

それがあなたがユニットテストしようとしている実際のコントロールであるなら、あなたは私を持っています。

于 2008-11-19T13:27:46.617 に答える
5

Model-View-Controller や Model-View-Presenter (別名 Humble Dialog) のさまざまな化身など、UI ロジックから UI プレゼンテーションを分離するのに役立つパターンがいくつかあります。Humble Dialog は、単体テストを簡単にするために特別に作成されました。これらの UI パターンのいずれかをデザイン アーセナルに含める必要があります。

しかし、単純なフォームの場合、フレームワークがそれをサポートしている場合、実際の UI コントロールに対して直接テストするのは非常に簡単であることがわかりました。Java Swing と Windows.Forms で完全にテスト ファーストの非常に堅牢な UI を構築しました。SWT や ASP.NET では管理できず、MVP に戻しました。

このようなことをテストするには...

[Test] public void ShouldCopyFromAvailableToSelectedWhenAddButtonIsCLicked(){
  myForm.AvailableList.Items.Add("red");
  myForm.AvailableList.Items.Add("yellow");
  myForm.AvailableList.Items.Add("blue");

  myForm.AvailableList.SelectedIndex = 1;
  myForm.AddButton.Click();

  Assert.That(myForm.AvaiableList.Items.Count, Is.EqualTo(2));
  Assert.That(myForm.SelectedList.Items[0], Is.EqualTo("yellow"));
}

...UI コントロールに対して直接作業しても問題なく動作します。ただし、マウスの移動、キーストローク、またはドラッグ アンド ドロップのテストを開始する場合は、Brian が提案したようなより堅牢な UI パターンを選択することをお勧めします。

于 2008-11-19T16:43:25.177 に答える
3

コードがSystem.Windows.Forms.Controlに依存している場合、提案している内容はコンパイルされません。ControlとTextboxのバージョンは単に間違ったタイプです。

代わりに、UIとロジックをインターフェイスで分離した場合、これを行うことができます...次のようなものです。

public interface ITextBox
{
    public string Text {get; set;}
}

public class TextBoxAdapter : ITextBox
{
    private readonly System.Windows.Forms.TextBox _textBox;
    public TextBoxAdapter(System.Windows.Forms.TextBox textBox)
    {
        _textBox = textBox;
    }

    public string Text
    {
        get { return _textBox.Text; }
        set { _textBox.Text = value; }
    }
}

public class YourClass
{
    private ITextBox _textBox;
    public YourClass(ITextBox textBox)
    {
        _textBox = textBox;
    }

    public void DoSomething()
    {
        _textBox.Text = "twiddleMe";
    }
}

次に、テストでは、モック、フェイク、またはスタブのITextBoxを作成して渡すだけです。

このようなことをするときは、少し高いレベルでインターフェイスを作成します... UI全体によく似たインターフェイスを作成し、UIにインターフェイスを実装させます。そうすれば、フォームコントロールであることを実際に知らなくても、必要なUIをすべていじることができます。

ちなみに、実際のコントロールを作成するアプローチを採用したい場合は、このブログ投稿を検討してください:http ://www.houseofbilz.com/archive/2008/10/12/winforms-automation-extensions.aspx

于 2008-11-19T13:28:14.790 に答える