0

私たちは NSubstitute を使用しているので、モックには単一のインターフェースが必要だと思います。スーパークラスを参照し、ポリモーフィズムを使用するコードもあります。

私が持っていたアイデア..

追加したメソッドと既存のメソッド (Value と Text など) の両方を使用してインターフェイスを作成し、既存のコードの参照をスーパークラスではなくそのインターフェイスを使用するように変更しますか?

TextBox をサブクラス化するのではなくラップします (よくわかりません - これは Adapter / Proxy パターンですか)。

更新(詳細):

TextBox をサブクラス化し、Value プロパティを追加する ValueTextBox クラスを作成しました。

public class ValueTextBox : TextBox
{
    /* ... */

    public ValueTextBox(/* ... */)
    {
        /* ... */
    }

    public string Value
    {
        get
        {
            /* ... */
        }
        set 
        {
            /* ... */
        }
    }
}

他のコードが予想される時間に get/set Text/Value を呼び出していることを確認したいと思います。

ノート:

  1. ValueTextBox に似た別のクラス IntegerTextBox があります。
  2. 他のコードでは、ポリモーフィズムを利用して、ValueTextBox/IntegerTextBox オブジェクトを TextBox 型の変数に格納することがあります。
4

3 に答える 3

1

一般的なアドバイスは、所有していないものをモックしないことです。(あなたは TextBox クラスを書いたり制御したりしていないので、それをモックするべきではありません。)

しかし、あなたの状況はあなたの状況です。では、なぜこれが必要なのかについてもう少し詳しく説明していただけますか? 代替案を見つけることができました。

更新: すべてのコントロールを共通のレベル (ValueProvider と呼ばれる役割 (インターフェイス)) に落としているようです。その場合、(入力として) 実装を受け入れ、ValueProvider.Value プロパティが期待どおりに機能するかどうかを検証する共通のテスト フィクスチャを作成できます。ValueProvider のさまざまな実装を渡します。基本型をモックしたい理由はありますか? カスタム派生のインスタンスを作成し、Value プロパティを呼び出すだけで、それが機能するかどうかを確認できます。

于 2012-04-05T12:21:39.417 に答える
0

テストしようとしているコードにもう少し情報を追加できれば、それは素晴らしいことです。あなたが書いたことに基づいて、いくつかのオプションを推測できます。

現時点で最も侵襲性が低いのは、おそらくあなたの質問で提案したアプローチでしょう。インターフェイスまたは共通の基本クラス/アダプターを偽造したいメンバーに追加して、virtual動的プロキシを使用するライブラリをモックすることでピックアップできるようにします(NSubstituteなど) 、Moq、FakeItEasy、Rhino モック)。

IInputControl<T>そのようなものがあればT Value { get; set;}、テストでそのタイプを置き換えることができます。IInputControl<T>ではなくとして参照を保存するようにコードを更新する必要がありますがTextBox、コードを の詳細から分離するので、それは悪いことではないかもしれませんTextBox

TextBoxもう 1 つのオプション (既に行っているかどうかは不明) は、Model-View-Presenter スタイルを使用し、ビューがメッセージを他のコントロールに変換する方法の詳細を単体テストしないことです。(エンド ツー エンド テストに受け入れテストを使用できます。)

例として、次のようなプレゼンターとビュー インターフェイスがあるとします。

public class PersonPresenter {
  public PersonPresenter(IPersonView view, IPersonQuery query) { ... }

  public void Load() {
    var person = query.Execute();
    view.Name = person.Name;
    view.Age = person.Age;
  }
}

public interface IPersonView {
  string Name { get; set; }
  int Age { get; set; }
}

次のようなものでテストできます。

[Test]
public void ShouldDisplayPersonOnLoad() {
  var view = Substitute.For<IPersonView>();
  var query = Substitute.For<IPersonQuery>();
  query.Execute().Returns(new Person("A", 20));

  var subject = new PersonPresenter(view, query);
  subject.Load();

  Assert.That(view.Name, "A");
  Assert.That(view.Age, 20);
}

その後、実際のビューを既存のコントロールに委任できます。これは単体テストではテストされていませんが、受け入れテストが可能であるか、ビューが変更されるたびに手動でテストされる可能性があります。理想的には、このコードは、あまり多くのバグを隠してしまわないように単純にする必要があります。アイデアは、ビューをできるだけ単純にすること、そして主にロジックではなく情報の外観に関心を持つことです。

public PersonView : IPersonView {
  // ...
  public string Name { 
    get { return nameTextBox.Value; } 
    set { nameTextBox.Value = value; }
  }
  public int Age { 
    get { return ageIntTextBox.Value; } 
    set { ageIntTextBox.Value = value; }
  }
}
于 2012-04-06T00:04:34.120 に答える