Is it acceptable to accept calls in your callbacks if you later confirm that the methods were called? Is this the preferred way to make sure my layout gets the expected parameters passed to it, or should I set a local variable in my callback and execute the statements in this instance?
I have a situation where I have some kind of logic in the Presenter class that outputs values ββbased on the input data and passes them to the Creator class. To check the logic in the Presenter class, I want to check that the corresponding derived values ββare observed when the Creator is called. I came up with an example below that works, but I'm not sure if I like this approach:
[TestFixture] public class WidgetCreatorPresenterTester { [Test] public void Properly_Generates_DerivedName() { var widgetCreator = new Mock<IWidgetCreator>(); widgetCreator.Setup(a => a.Create(It.IsAny<Widget>())) .Callback((Widget widget) => Assert.AreEqual("Derived.Name", widget.DerivedName)); var presenter = new WidgetCreatorPresenter(widgetCreator.Object); presenter.Save("Name"); widgetCreator.Verify(a => a.Create(It.IsAny<Widget>()), Times.Once()); } }
I am worried that without a Verify call at the end, there is no guarantee that the call in the callback will be called. Another approach would be to set a local variable in the callback:
[Test] public void Properly_Generates_DerivedName() { var widgetCreator = new Mock<IWidgetCreator>(); Widget localWidget = null; widgetCreator.Setup(a => a.Create(It.IsAny<Widget>())) .Callback((Widget widget) => localWidget = widget); var presenter = new WidgetCreatorPresenter(widgetCreator.Object); presenter.Save("Name"); widgetCreator.Verify(a => a.Create(It.IsAny<Widget>()), Times.Once()); Assert.IsNotNull(localWidget); Assert.AreEqual("Derived.Name", localWidget.DerivedName); }
I feel that this approach is less error prone as it is more explicit and it is easier to see that Assert statements will be called. Is one approach preferable to another? Is there an easier way to check the input parameter passed to the layout that I am missing?
In case this is useful, here is the rest of the code for this example:
public class Widget { public string Name { get; set; } public string DerivedName { get; set; } } public class WidgetCreatorPresenter { private readonly IWidgetCreator _creator; public WidgetCreatorPresenter(IWidgetCreator creator) { _creator = creator; } public void Save(string name) { _creator.Create( new Widget { Name = name, DerivedName = GetDerivedName(name) }); }
EDIT
I updated the code to make the second approach that I outlined in the question easier to use. I pulled the creation of the expression used in Setup / Verify to a separate variable, so I only need to define it once. I feel that this method is what I like best with, it is easy to configure, and fails with good error messages.
[Test] public void Properly_Generates_DerivedName() { var widgetCreator = new Mock<IWidgetCreator>(); Widget localWidget = null; Expression<Action<IWidgetCreator>> expressionCreate = (w => w.Create(It.IsAny<Widget>())); widgetCreator.Setup(expressionCreate) .Callback((Widget widget) => localWidget = widget); var presenter = new WidgetCreatorPresenter(widgetCreator.Object); presenter.Save("Name"); widgetCreator.Verify(expressionCreate, Times.Once()); Assert.IsNotNull(localWidget); Assert.AreEqual("Derived.Name", localWidget.DerivedName); }