> I'm getting some bizarre behavior from Rhino Mocks. It's possible that
> my test setup is wrong, and there is a glaring error that I'm staring
> right at, but I've been over the code several times and don't see it.
> The following test fails with a NullReference exception because
> view.ValueDifferenceValidator is null when the view load event is
> raised:
> [NUNIT.TestFixture]
> public class ValueDifferenceValidationPresenterTest
> {
> private MockRepository mockRepository;
> private IValueDifferenceValidationView mockView;
> private IServerValidator mockValidator;
> private ITextControl from;
> private ITextControl to;
> private IEventRaiser viewLoad;
> private IEventRaiser serverValidate;
> [NUNIT.SetUp]
> public void CreateTestDoubles()
> {
> mockRepository = new MockRepository();
> mockView =
> mockRepository.DynamicMock<IValueDifferenceValidationView>();
> mockValidator =
> mockRepository.DynamicMock<IServerValidator>();
> from = mockRepository.Stub<ITextControl>();
> to = mockRepository.Stub<ITextControl>();
> Expect.Call(mockView.ValueDifferenceValidator).Return
> (mockValidator);
> Expect.Call(mockView.FromValueTextBox).Return(from);
> Expect.Call(mockView.ToValueTextBox).Return(to);
> viewLoad =
> Expect.Call(delegate { mockView.Load +=
> null; }).IgnoreArguments().GetEventRaiser();
> serverValidate =
> Expect.Call(delegate { mockValidator.ServerValidate +=
> null; }).IgnoreArguments().GetEventRaiser();
> }
> private void EndArrange()
> {
> mockRepository.ReplayAll();
> }
> [NUNIT.Test]
> public void Lower_To_Value_Should_Not_Be_Valid()
> {
> // Arrange
> ServerValidateEventArgs validationArguments = new
> ServerValidateEventArgs(String.Empty, true);
> EndArrange();
> // Act
> from.Text = "20";
> to.Text = "18";
> IValueDifferenceValidationPresenter presenterUnderTest =
> new ValueDifferenceValidationPresenter(mockView);
> viewLoad.Raise(mockView, EventArgs.Empty);
> serverValidate.Raise(mockValidator, validationArguments);
> // Assert
> NUNIT.Assert.IsFalse(validationArguments.IsValid);
> }
> }
> Here is the presenter being tested and view interface:
> public interface IValueDifferenceValidationView : IView
> {
> IServerValidator ValueDifferenceValidator { get; }
> ITextControl FromValueTextBox { get; }
> ITextControl ToValueTextBox { get; }
> }
> public class ValueDifferenceValidationPresenter :
> IValueDifferenceValidationPresenter
> {
> private readonly IValueDifferenceValidationView view;
> public ValueDifferenceValidationPresenter
> (IValueDifferenceValidationView view)
> {
> this.view = view;
> this.view.Load += new EventHandler(view_Load);
> }
> private void view_Load(object sender, EventArgs e)
> {
> //this.view.ValueDifferenceValidator.ServerValidate += new
> ServerValidateEventHandler(ValueDifferenceValidator_ServerValidate);
> this.view.ValueDifferenceValidator.ServerValidate +=new
> EventHandler<ServerValidateEventArgs>
> (ValueDifferenceValidator_ServerValidate);
> }
> private void ValueDifferenceValidator_ServerValidate(object
> source, ServerValidateEventArgs args)
> {
> // Some logic
> }
> }
> I expect the test to pass because the following works perfectly:
> [NUNIT.TestFixture]
> public class SomeOtherValidationPresenterTest
> {
> private MockRepository mockRepository;
> private ISomeOtherValidationView mockView;
> private IServerValidator mockValidator;
> private IEventRaiser viewLoad;
> private IEventRaiser serverValidate;
> [NUNIT.SetUp]
> public void InitializeMocks()
> {
> mockRepository = new MockRepository();
> mockView =
> mockRepository.DynamicMock<ISomeOtherValidationView>();
> mockValidator =
> mockRepository.DynamicMock<IServerValidator>();
> Expect.Call(mockView.ValueValidator).Return
> (mockValidator);
> viewLoad =
> Expect.Call(delegate { mockView.Load +=
> null; }).IgnoreArguments().GetEventRaiser();
> serverValidate =
> Expect.Call(delegate { mockValidator.ServerValidate +=
> null; }).IgnoreArguments().GetEventRaiser();
> }
> public void EndArrange()
> {
> mockRepository.ReplayAll();
> }
> [NUNIT.Test]
> public void Empty_Value_Should_Be_Valid()
> {
> // Arrange
> ServerValidateEventArgs validationArguments = new
> ServerValidateEventArgs(String.Empty, false);
> EndArrange();
> // Act
> ISomeOtherValidationPresenter presenterUnderTest = new
> SomeOtherValidationPresenter(mockView);
> viewLoad.Raise(mockView, EventArgs.Empty);
> serverValidate.Raise(mockValidator, validationArguments);
> //Assert
> NUNIT.Assert.IsTrue(validationArguments.IsValid);
> }
> }
> public class SomeOtherValidationPresenter :
> ISomeOtherValidationPresenter
> {
> private readonly ISomeOtherValidationView view;
> public SomeOtherValidationPresenter(ISomeOtherValidationView
> view)
> {
> this.view = view;
> this.view.Load += new EventHandler(view_Load);
> }
> private void view_Load(object sender, EventArgs e)
> {
> this.view.ValueValidator.ServerValidate +=new
> EventHandler<ServerValidateEventArgs>(ValueValidator_ServerValidate);
> }
> private void ValueValidator_ServerValidate(object source,
> ServerValidateEventArgs args)
> {
> // Some logic
> }
> }
> public interface ISomeOtherValidationView : IView
> {
> IServerValidator ValueValidator { get; }
> }
> When I debug in Visual Studio I actually see some more strange
> behavior... It looks like on the initial valuation of the
> ValueDifferenceValidator, FromValueTextBox, and ToValueTextBox
> properties (that is, the evaluation done at first by the debugger),
> the mockView **IS** returning the mocks and stubs I have set up.
> Further evaluation returns null for these properties. I suspect there
> is something I'm doing wrong with the record/replay model, but both
> scenarios are almost **exactly** the same.
> Can anyone explain this? What obvious thing am I missing?