locked
Feature Disparity between Stubs and Rhino Mocks

    Question

  • So I have the following interface:

        public interface IAddAddressForm
        {
            string FirstName { get; set; }
            string LastName { get; set; }
            string Address1 { get; set; }
            string Address2 { get; set; }
            string City { get; set; }
            string State { get; set; }
            string ZipCode { get; set; }
            bool OKButtonEnabled { get; set; }
            DialogResult DialogResult { get; set; }
            DialogResult ShowCancelMessage();
        }

    In RhinoMocks, if I do this:

        var form = MockRepository.GenerateStub<IAddAddressForm>();
        form.FirstName = "bob";

    Then this does not have any issues.

    However, if I do this with Stubs:

        form = new SIAddAddressForm();
        ((IAddAddressForm)form).FirstName = "bob";

    I get the following Error:

    Initialization method TestAddressBook.TestAddAddressMediator.MyTestInitialize threw exception. Microsoft.Moles.Framework.Behaviors.BehaviorNotImplementedException:  Microsoft.Moles.Framework.Behaviors.BehaviorNotImplementedException: SIAddAddressForm.AddressBook.IAddAddressForm.set_FirstName(String) was not stubbed..

    So, to get this to work I could do this:

        form.FirstNameGet = () => "bob";

    But that only helps me if I know that first name should always be "bob".  What about when in my code under test I have something like this:

            private void EnterAddressInfo(AddressItem item, IAddAddressForm addAddressForm)
            {
                addAddressForm.FirstName = item.FirstName;
                addAddressForm.LastName = item.LastName;
                addAddressForm.Address1 = item.Address1;
                addAddressForm.Address2 = item.Address2;
                addAddressForm.State = item.State;
                addAddressForm.ZipCode = item.ZipCode;
                addAddressForm.City = item.City;
                mediator.FirstNameChanged();
                mediator.LastNameChanged();
                mediator.Address1Changed();
                mediator.StateChanged();
                mediator.StateChanged();
                mediator.CityChanged();
                mediator.ZipCodeChanged();
            }

    Now I need to manually setup each get and set for each property.  Something that is done automatically for me by Rhino Mocks :(

    NOTE: I tried form.AttachBackingFieldToFirstName(); and it did not make the above example work (the one that failed with the exception).  Even if it did, that would be very frustrating to have to call that on every property in every object when it is done automatically in Rhino mocks.

    Hopefully I am missing a setting somewhere that can help on this.  I would like to have my company just standardize on Moles and Stubs, but it can't be way way harder to do things or I will get serious push back.

    Monday, September 13, 2010 8:17 PM

Answers

  • If you attach the BehavedBehaviors.Default to the InstanceBehavior property on the stub, it should simply happen. You can also change for stubs instance by doing

        BehavedBehaviors.Current = BehavedBehaviors.Default;

    (pg 15 of the reference manual)


    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    • Marked as answer by Vaccanoll Wednesday, September 15, 2010 3:19 PM
    Monday, September 13, 2010 10:32 PM
  • That is definitely a bug (and a missing test). state.GetGetter() should return MolesDelegates.Func<string>. This issue is fixed in v0.94, unfortunately there's no workaround.
    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    • Marked as answer by Vaccanoll Wednesday, September 15, 2010 3:19 PM
    Wednesday, September 15, 2010 8:59 AM

All replies

  • If you attach the BehavedBehaviors.Default to the InstanceBehavior property on the stub, it should simply happen. You can also change for stubs instance by doing

        BehavedBehaviors.Current = BehavedBehaviors.Default;

    (pg 15 of the reference manual)


    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    • Marked as answer by Vaccanoll Wednesday, September 15, 2010 3:19 PM
    Monday, September 13, 2010 10:32 PM
  • Thanks for the heads up on that.  I know understand what behaviors are as well (I like them!)

    But what you suggested did not result in a clean run.  This is what I did:

        form = new SIAddAddressForm();
        form.InstanceBehavior = BehavedBehaviors.DefaultValue;

    I also tried this:

        form = new SIAddAddressForm();
        BehavedBehaviors.Current = BehavedBehaviors.DefaultValue;

    Both resulted in this error message when I ran the test:

         Test method TestAddressBook.TestAddAddressMediator.TestOKButtonEnabled threw exception:  System.InvalidCastException:
         Unable to cast object of type 'Func[System.String]' to type 'Func`1[System.String]'..

    I get this when run addAddressForm.FirstName = item.FirstName; from the method EnterAddressInfo shown above.  It is addAddressForm.FirstName that is causing the issue.  (When I look at it in the watch window it says:

         'addAddressForm.FirstName' threw an exception of type 'System.InvalidCastException'    string {System.InvalidCastException}

    So.... what am I doing wrong?

    _________

    Later Note With More Info:

    Here is the Call Stack that I am getting when the test fails:

       AddressBook.Moles.SIAddAddressForm.AttachBackingFieldToFirstName()
       AddressBook.Moles.SIAddAddressForm.AddressBook.IAddAddressForm.set_FirstName(String value)
       TestAddressBook.TestAddAddressMediator.EnterAddressInfo(AddressItem item, IAddAddressForm addAddressForm) in C:\src\ESP-Tester
               \Episode3-TDD\TDD_AddressBook\AddressBookFinal\TestAddressBook\TestAddAddressMediator.cs: line 138
       TestAddressBook.TestAddAddressMediator.TestOKButtonEnabled() in C:\src\ESP-Tester\Episode3-TDD\TDD_AddressBook\AddressBookFinal
               \TestAddressBook\TestAddAddressMediator.cs: line 82


    The code for AttachBackingFieldToFirstName is here:

    /// <summary>Attaches delegates to emulate SIAddAddressForm.FirstName as a property with a backing field</summary>
    public void AttachBackingFieldToFirstName()
    {
        mmf::Microsoft.Moles.Framework.Behaviors.IBehavior _behavior =
            ((mmf::Microsoft.Moles.Framework.Behaviors.IBehaved)this).InstanceBehavior;
        string initialValue;
        if (this.FirstNameSetString == (mmf::Microsoft.Moles.Framework.MolesDelegates.Action<string>)null &&
            this.FirstNameGet == (mmf::Microsoft.Moles.Framework.MolesDelegates.Func<string>)null &&
            _behavior.TryGetValue<string>((object)this, out initialValue))
        {
          mmf::Microsoft.Moles.Framework.Stubs.StubValueHolder<string> state
             = new mmf::Microsoft.Moles.Framework.Stubs.StubValueHolder<string>(initialValue);
          this.FirstNameGet = (mmf::Microsoft.Moles.Framework.MolesDelegates.Func<string>)(state.GetGetter());
          this.FirstNameSetString = (mmf::Microsoft.Moles.Framework.MolesDelegates.Action<string>)(state.GetSetter());
        }
    }

    Tuesday, September 14, 2010 7:15 PM
  • That is definitely a bug (and a missing test). state.GetGetter() should return MolesDelegates.Func<string>. This issue is fixed in v0.94, unfortunately there's no workaround.
    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    • Marked as answer by Vaccanoll Wednesday, September 15, 2010 3:19 PM
    Wednesday, September 15, 2010 8:59 AM
  • Any new updates to the release date of 0.94.
    Wednesday, September 15, 2010 3:20 PM
  • We're testing the bits. Should happen within a few days.
    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    Wednesday, September 15, 2010 8:44 PM
  • Release is out.
    Jonathan "Peli" de Halleux - Try Pex online at www.pexforfun.com!
    Friday, September 17, 2010 5:47 PM