I am using the template implementation of Model-View-Presenter in an ASP.NET WebForms application. In my view, there are two events that signal that the user has filled in enough fields on the domain model to trigger a duplication check, and the other is the usual Save event. My pseudo code is as follows:
public class ItemNewPresenter : PresenterBase<IItemNewView> { public IItemService Service { get; private set; } public IItemNewView View { get; private set; } public ItemNewPresenter(IItemService service, IItemNewView view) { Service = service; View = view; View.OnSave += DoItemSave; View.OnItemIsDuplicateCheck+= DoItemIsDuplicateCheck; } private void DoItemIsDuplicateCheck(object sender, CheckItemDuplicateEventArgs e) { CheckForItemDuplication(e.Item); } private void CheckForItemDuplication(Item item){ if (Service.IsDuplicateItem(item)) { View.RedirectWithNotification(BuildItemUrl(item), "This item already exists"); } } private void DoItemSave(object sender, SaveItemEventArgs e) { DoItemIsDuplicateCheck(this, e.ToItemDuplicateEventArgs()); Service.Save(e.Item); } }
Here is my test to ensure that my host behaves correctly when OnItemIsDuplicateCheck is raised from a view:
[Test] public void presenter_checking_for_existing_item_should_call_redirect_if_found() { var service = new Mock<IItemService>(); var view = new Mock<IItemNewView>(); var presenter = new ItemNewPresenter (service.Object, view.Object); var onCheckExistingHandler = view.CreateEventHandler <CheckItemDuplicateEventArgs>(); view.Object.OnExistingDenominatorCheck += onCheckExistingHandler; var eventArgs = new CheckItemDuplicateEventArgs(); service.Setup(s => s.IsDuplicate(It.Is<CheckItemDuplicateEventArgs>(c => c.Equals(eventArgs)))).Returns(true); onCheckExistingHandler.Raise(eventArgs); view.Verify(v => v.RedirectWithNotification(It.IsAny<String>(), It.IsAny<string>()), Times.Once()); service.Verify(); }
To ensure consistency, I would like to have the same double check when View raises the OnSave . My question is related to how I should write my test when one of the methods I want to test ( CheckForItemDuplication ) is declared in the tested class. An alternative to checking the method call for SUT (bad) would be to write my save test with a lot of duplicated code (the installation and approval of all my poppies will be copied from the above test), and also makes the unit test less focused.
[Test] public void presenter_saving_item_should_check_for_dupe_and_save_if_not_one() {
I think that TDD will offer to bring this private method into a separate class, which will cooperate with my Master and will be introduced through DI. But adding another dependency to my Presenter for functionality that doesn't seem worthy of an independent abstraction * and * is an internal part of my Lead's implementation, it seems ... well ... crazy. Am I here from here? There must be some kind of design template or refactoring that I can apply to avoid the need to turn a private method into a dependency.
source share