我正在尝试测试使用 ASP.NET WebFormsMVP 创建的演示者。我正在使用“监督控制器”模式构建它,因此视图负责从模型中更新自身。我简化了以下带有文本框、按钮和标签的页面示例。您在文本框中输入并按下按钮,文本HelloWorld! <YOUR TEXT>
就会放在标签上。
下面的示例代码,但简而言之:
- button_click 将引发查看事件。
- Presenter 订阅此 ViewEvent 并捕获 args(即消息)
- Presenter 完成工作(字符串连接)并更新模型
- 视图重新绑定到 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;
}
我的问题在于测试。
由于 View 负责从模型中更新自身,Presenter 只设置 Model.Message 属性......所以在单元测试中,我想做以下事情。
- 嘲笑我的
IHelloWorldView
- 用 Mock 实例化我的 Present。
- 在 Mock 上触发事件
- 验证当前设置了 Mock 的 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; }
}
我的其他选择是使用被动视图模式并将 asp:label Text 公开为 IHelloWorldView 上的字符串属性,并直接从 Presenter 设置它...然后我应该能够对其进行测试。
- 从测试的角度来看,被动视图是更好的方法吗?
- 我是否有必要同时模拟我的模型(我不确定在 WebFormsMVP 中是否可行?或者
- 我需要将我的模型的所有属性都设为虚拟或
- 我在某处错过了重点吗?