views:

111

answers:

1

I am trying to experiment with RhinoMocks, where I have to say I am a newbie and probably I don't get some obvious thing here. What I'm doing is something like :

    [TestMethod]
    public void SaveResponsibleUserFromChangeset()
    {
        var action = mocks.StrictMock<GenomeAction>();
        var changeset = new ActionChangeset();

        changeset.ResponsibleUser = new ChangeableProperty<UserIdentity>("Administrator") {IsChanged = true};
        changeset.MarkAll(true);

        using(mocks.Record())
        {
            Expect.Call(action.ResponsibleUser).SetPropertyAndIgnoreArgument();
        }

        using(mocks.Playback())
        {
            var persistor = new ActionPersistor(new MockIdentityResolver());
            persistor.SaveActionChanges(changeset, action);
        }

        action.VerifyAllExpectations();
    }

    private class MockIdentityResolver : IIdentityResolver
    {
        public GenomeUser GetUser(UserIdentity identity)
        {
            var user = mocks.DynamicMock<GenomeUser>();
            user.Username = identity.Username;
            return user;
        }
    }

The intention is to have a very simple test which checks whether the SaveActionChanges method sets the ResponsibleUser property. As a part of this, it needs to resolve the user identity using the resolver, for which I have provided a mock implementation. Unfortunately, it seems I can't just return back another mock within the Playback mode, because it says (on the closing bracket of the second using) that The action is invalid when the object (of type GenomeUser) is in record state.

Any ideas of what is causing the trouble and how to overcome it ?

+4  A: 

I think you need to create you new MockIdentityResolver() outside the mocks.Playback().

[TestMethod]
public void SaveResponsibleUserFromChangeset()
{
    var action = mocks.StrictMock<GenomeAction>();
    var changeset = new ActionChangeset();
    var identityResolver;
    changeset.ResponsibleUser = new ChangeableProperty<UserIdentity>("Administrator") {IsChanged = true};
    changeset.MarkAll(true);

    using(mocks.Record())
    {
        Expect.Call(action.ResponsibleUser).SetPropertyAndIgnoreArgument();
        identityResolver = new MockIdentityResolver()
    }

    using(mocks.Playback())
    {
        var persistor = new ActionPersistor(identityResolver);
        persistor.SaveActionChanges(changeset, action);
    }

    action.VerifyAllExpectations();
}

private class MockIdentityResolver : IIdentityResolver
{
    public GenomeUser GetUser(UserIdentity identity)
    {
        var user = mocks.DynamicMock<GenomeUser>();
        user.Username = identity.Username;
        return user;
    }
}

you should look at using the AAA syntax, it seems to be generally accepted that it's a clearer way of using stuff.

Sam Holder
I have used your advice and rewritten the thing completely in AAA syntax way and now it's working like charm. Thanks ;)
Thomas Wanner
+1 for also mentioning the superior AAA syntax
Wim Coenen
Another +1 from me for the AAA syntax; the Rhino Mocks author, Oren Eini, has mentioned the next version of his framework will do away with the Record/Playback syntax, and offer only the AAA syntax.
Judah Himango