Ordered expectations for AAA syntax

273 views
Skip to first unread message

Alex McMahon

unread,
Jun 23, 2009, 6:02:37 AM6/23/09
to Rhino.Mocks
I've found doing ordered expectations to be a bit of a pain since
Rhino Mocks 3.5 introduced AAA syntax, it seems to be one of the few
areas where you have to drop back to using the old record/replay
syntax, and it's making my test fixtures awfully complicated and
fragile.

So other than trying to find a nice way to do it in RhinoMocks itself
I've got a workaround that I've been using, and I wondered what others
thought of it.

[TestMethod()]
public void ViewTitleSetBeforeShownInWorkspace()
{
//arrange
var mockView=MockRepository.GenerateMock<IView>();
bool viewTitleSet=false;
mockView.Stub(x=>x.Title=Arg<string>.Is.Anything)
.WhenCalled(a=>{viewTitleSet=true});
mockView.Stub(x=>x.ShowInWorkspace("MyWorkspace"))
.WhenCalled(a=>{Assert.IsTrue(viewTitleSet, "View title should
have been set first");});

//act
var target=new Presenter(mockView);
target.Initialize();

//assert
mockView.AssertWasCalled(x=>x.ShowInWorkspace("MyWorkspace"));
}

Ayende Rahien

unread,
Jun 23, 2009, 1:54:25 PM6/23/09
to Rhino...@googlegroups.com
You cannot use Ordered with AAA, that was judged to be rare enough and the complexity of providing this feature high enough to not do it.

Kenneth Xu

unread,
Jun 27, 2009, 11:52:51 AM6/27/09
to Rhino...@googlegroups.com
Just 2 cents worth as I didn't really look into the source code so
forgive me if all I'm talking is crap.

I assume we internally record each call so we can assert later. If we
keep an atomic running number within each mock instance, and record it
with the each call. We can probably say:

mockView.AssertWasCalled(x=>x.ShowInWorkspace("MyWorkspace")).Before(x=>...);

Cheers,
Kenneth

Kenneth Xu

unread,
Jun 27, 2009, 2:59:50 PM6/27/09
to Rhino...@googlegroups.com
Just want to confirm the idea :) I check out the RhinoMocks. It turn
out to be quite straightforward, thanks to nice design of it, I
created a class called CallRecord which keeps a thread safe sequencer
that is increased for each call and later use that information to
determine the order of each call.
public class CallRecord
{
private static long sequencer = long.MinValue;

internal CallRecord()
{
Sequence = Interlocked.Increment(ref sequencer);
}
internal object[] Arguments { get; set; }
internal long Sequence { get; private set; }
internal MethodInfo Method { get; set; }
internal IMockedObject MockObject { get; set; }
}

Then make AssertWasCalled methods return an IList<CallRecord>. And
added an extension method:

public static void Before(this IList<CallRecord> beforeCalls,
IList<CallRecord> afterCalls)

Now you can do this to verify the order:
mock1.AssertWasCalled(m1=>m1.MethodBefore())
.Before(mock2.AssertWasCalled(m2=>MethodAfter());

I have attached the patch. And there is the unit test which is also
included in the patch.

Cheers,
Kenneth

[TestFixture] public class BeforeExtensionMethodTest
{
public interface IBefore
{
void MethodBefore();
}

public interface IAfter
{
void MethodAfter();
}

[Test] public void
Before_succeeds_if_beforeCalls_occured_before_afterCalls()
{
var mockBefore = MockRepository.GenerateStub<IBefore>();
var mockAfter = MockRepository.GenerateStub<IAfter>();
mockBefore.MethodBefore();
mockBefore.MethodBefore();
mockAfter.MethodAfter();
mockAfter.MethodAfter();
mockAfter.MethodAfter();
mockBefore.AssertWasCalled(b => b.MethodBefore())
.Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
}

[ExpectedException(typeof(ExpectationViolationException))]
[Test] public void
Before_chokes_if_one_of_beforeCalls_occured_after_any_of_afterCalls()
{
var mockBefore = MockRepository.GenerateStub<IBefore>();
var mockAfter = MockRepository.GenerateStub<IAfter>();
mockBefore.MethodBefore();
mockAfter.MethodAfter();
mockBefore.MethodBefore();
mockAfter.MethodAfter();
mockAfter.MethodAfter();
mockBefore.AssertWasCalled(b => b.MethodBefore())
.Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
OrderedAAA.patch

René M. Andersen

unread,
Aug 18, 2011, 7:23:00 AM8/18/11
to rhino...@googlegroups.com, Rhino...@googlegroups.com
Hi all,

Has this patch never been accepted into Rhino Mocks? I am using version 3.6 an can't find the mentioned Before() method?


Reply all
Reply to author
Forward
0 new messages