I am trying to test a Presenter created using ASP.NET WebFormsMVP. I build it using the "Controller" template, so View is responsible for updating itself from the model. I simplified the following example page with a text box, button, and label. You enter a text field and click a button, and the text is HelloWorld! <YOUR TEXT> HelloWorld! <YOUR TEXT> is placed on the label.
The code example below, but in a nutshell:
- button_click will trigger a view event.
- The host subscribes to this ViewEvent and picks up the arguments (for example, a message)
- The host does the work (string concatenation) and updates the Model
- the view rechecks the Model.Message property and everything works fine.
//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; }
My problem is testing.
Since the view is responsible for updating itself from the model, Presenter sets only the Model.Message property ... so in Unit Test I want to do the following.
IHelloWorldView my IHelloWorldView- Create an instance of My Present using Mock.
- Run an event in Mock
- Ensure that the Model.Message property of the layout is currently set.
[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()); }
But this will not work if I do not explain the Message property. The property of my model is virtual, which I really do not want to do. eg.
//Model public class HelloWorldModel { public string Message { get; set; } }
My other option is to use a passive view template and set asp: label Text as a row property in IHelloWorldView and set it directly from Presenter ... and then I have to check it.
- Passive Viewing the best approach in terms of testing?
- Do I need to either have Mock my Model (which I'm not sure about WebFormsMVP? OR
- I need to do all the properties of my Virtual model OR
- Did I miss something?
source share