How should I unit test my WebFormMVP presenters with Moq'd views when using the control controller template

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?
+4
source share
1 answer

You customize the layout of the view using DefaultValue.Mock, so your view will have an initialized Model property. Instead of using Moq to check the model value, just check the message directly on your model:

 Assert.That(mock.Object.Model.Message, Is.EqualTo(expected)); 

The beauty of this small (but semantically equal) change is that your layout suddenly becomes a stub, and you check the final result instead of the detailed implementation details. As for your questions, it would be nice to design your system in terms of testability, but I wouldn’t virtualize or just interfaces to make it convenient for Moq; make a SOLID architecture, not necessarily Moq-able.

+1
source

Source: https://habr.com/ru/post/1393819/


All Articles