ASP.NET WebFormsMVP を使用して作成されたプレゼンターをテストしようとしています。「監視コントローラー」パターンを使用して構築しているため、ビューはモデルからの更新を担当します。テキストボックス、ボタン、およびラベルを含むページの次の例を簡略化しました。テキストボックスに入力してボタンを押すと、テキストHelloWorld! <YOUR TEXT>
がラベルに表示されます。
以下のサンプルコードですが、一言で言えば:
- button_click は View イベントを発生させます。
- プレゼンターはこの ViewEvent をサブスクライブし、引数 (つまりメッセージ) をキャッチします。
- プレゼンターが作業 (文字列連結) を実行し、モデルを更新します
- ビューは Model.Message プロパティに再バインドされ、すべて正常に機能します。
//Model
public class HelloWorldModel {
public string Message { get; set; }
}
//Args
public class HelloWorldEventArgs : EventArgs {
public string Message { get; set; }
}
//View
public interface IHelloWorldView : IView<HelloWorldModel> {
event EventHandler<HelloWorldEventArgs> SendMessage;
}
//Presenter
public class HelloWorldPresenter : Presenter<IHelloWorldView>
{
private readonly EventHandler<HelloWorldEventArgs> SendMessageDelegate;
public HelloWorldPresenter(IHelloWorldView view) : base(view)
{
SendMessageDelegate = ((s, e) => SendMessageReceived(e.Message));
View.SendMessage += SendMessageDelegate;
}
public override void ReleaseView()
{
View.SendMessage -= SendMessageDelegate;
}
public void SendMessageReceived(string message)
{
View.Model.Message = string.Format("Hello World! - {0}", message);
}
}
//View implementation
[PresenterBinding(typeof(HelloWorldPresenter))]
public partial class HelloWorld : MvpPage<HelloWorldModel>,IHelloWorldView
{
protected void EchoButtonClick(object sender, EventArgs e)
{
if(SendMessage != null)
{
var args = new HelloWorldEventArgs {Message = MessageTextBox.Text};
SendMessage(sender, args);
}
}
public event EventHandler<HelloWorldEventArgs> SendMessage;
}
私の問題はテストにあります。
ビューはモデルから自分自身を更新する責任があるため、プレゼンターは Model.Message プロパティのみを設定します...そのため、単体テストでは次のことを行います。
- 私のモック
IHelloWorldView
- モックでプレゼントをインスタンス化します。
- モックでイベントをトリガーする
- 現在、モックの Model.Message プロパティが設定されていることを確認します。
[TestMethod]
public void TestMethod1()
{
var input = "My Message";
var expected = string.Format("Hello World! - {0}", input);
var mock = new Mock<IHelloWorldView>
{
DefaultValue = DefaultValue.Mock
};
var pres = new HelloWorldPresenter(mock.Object);
mock.Raise(m =>
m.SendMessage += null,
new HelloWorldEventArgs { Message = input });
mock.VerifySet(view =>
view.Model.Message = It.Is<string>(s => s == expected),
Times.Once());
}
しかし、モデルのプロパティを明示的にMessage
仮想としてマークしない限り、これは機能しません。これは本当にやりたくないことです。例えば
//Model
public class HelloWorldModel {
public string Message { get; set; }
}
私の他のオプションは、パッシブ ビュー パターンを使用し、IHelloWorldView で asp:label テキストを文字列プロパティとして公開し、それをプレゼンターから直接設定することです...その後、テストできるはずです。
- テストの観点からすると、パッシブ ビューの方が優れたアプローチですか?
- また、モデルをモックする必要がありますか(WebFormsMVPで可能かどうかはわかりませんか?または
- モデル仮想 OR のすべてのプロパティを作成する必要があること
- どこかでポイントを逃しましたか?