我正在尝试测试使用ASP.NET WebFormsMVP创建的Presenter。我正在使用“监督控制器”模式构建它,因此View负责从模型中更新自身。我简化了以下带有文本框,按钮和按钮的页面示例。标签。您输入文本框&amp;按下按钮,文本HelloWorld! <YOUR TEXT>
将被放置在标签上。
下面的示例代码,但简而言之:
//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
[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
属性标记为虚拟而我不想做,否则这将无效。 e.g。
//Model
public class HelloWorldModel {
public string Message { get; set; }
}
我的其他选项是使用被动视图模式并在IHelloWorldView上将asp:标签Text作为字符串属性公开,并直接从Presenter设置...然后我应该能够测试它。
答案 0 :(得分:1)
您正在使用DefaultValue.Mock设置view-mock,因此您的视图将具有初始化的Model属性。不要使用Moq检查模型的值,只需直接在模型上检查消息:
Assert.That(mock.Object.Model.Message, Is.EqualTo(expected));
这个小的(但在语义上相等)变化的美妙之处在于你的模拟突然变成了一个存根而你正在测试最终结果而不是细节的实现细节。至于你的问题,在可测试性方面设计你的系统是一件好事,但我不会开始虚拟化或接口所有东西只是为了使它对Moq友好;制作一个SOLID架构,而不是Moq-able。