Want to show your appreciation?
Please a cup of tea.

Thursday, September 10, 2009

How NUnit Handles Test Fixture as Inner Class

The Problem

Will NUnit execute the test fixture defined as inner class when I test run the enclosing test fixture? The answer is, it depends (as of version 2.5.2). In most of cases it won't, but if the enclosing test fixture is a generic type, it will.

Here is the test case to reproduce this:

namespace Demo
{
    [TestFixture] public class A { //plain normal
        [Test] public void Bar() { }
        [TestFixture] public class Inner {
            [Test] public void Foo() {}
        }
    }
 
    [TestFixture(typeof(int))] public class B<T> { // generic
        [Test] public void Bar() { }
        [TestFixture(typeof(int))] public class Inner {
            [Test] public void Foo() {}
        }
    }
 
    [TestFixture("dummy")] public class C { // parameterized non-generic
        public C(string dummy){}
        [Test] public void Bar() { }
        [TestFixture(typeof(int))] public class Inner {
            [Test] public void Foo() { }
        }
    }
}

And the result:

C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.A" /labels
Selected test: Demo.A
***** Demo.A.Bar
 
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0262504 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0
 
C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.B<T>" /labels
Selected test: Demo.B<T>
***** Demo.B`1+Inner[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Foo
***** Demo.B`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Bar
 
Tests run: 2, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0337505 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0
 
C:\Demo>nunit-console.exe Demo.Tests.dll /run="Demo.C" /labels
Selected test: Demo.C
***** Demo.C.Bar
 
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0350005 seconds
  Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

My Thoughts

Now which behavior do I prefer? I would like to include the inner test fixture classes when running the enclosing one. Why? that's the only reason so far I need to create inner test fixture class. And here is the use case:

  1. I have MyCollection<T> : ICollection<T>, ICollection that is the subject under test.
  2. I have common reusable test fixture CollectionTestFixture<T> and CollectionTestFixture contain functional test cases for types that implement ICollection<T> and/or ICollection.
Test implementation A, Create three(3) separate test fixtures
  • MyCollectionGenericTests<T> : CollectionTestFixture<T>
  • MyCollectionNonGenericTests : CollectionTestFixuture
  • MyCollectionTests<T> // specific test cases

Pros:

  • Simple
  • Works

Cons:

  • Must run 3 test fixture to test one class
  • Difficult (impossible if using TD.Net) to run overall code coverage for MyCollection<T> class
  • Test result are not grouped together when there is MyCollectionSomeElseTest.
Test implementation B, use dedicated namespace
  • MyCollection.GenericTests<T> : CollectionTestFixture<T>
  • MyCollection.NonGenericTests : CollectionTestFixuture
  • MyCollection.Tests<T> // specific test cases

Pros:

  • Works
  • Can easily run all tests for MyCollection and get overall coverage

Cons:

  • Creating one folder (matching namespace) for one class to be tested result in very busy project layout and hard to navigate when there are a lot of such scenarios.
  • There will be a lot of repeated type names, e.g. GenericTests<T>. Otherwise MyCollection.MyCollectionGenericTests<T> makes the label reads much longer which is a bad thing.
Test implementation C, use inner classes
  • MyCollectionTests<T> // specific test cases
  • MyCollectionTests.AsGeneric<T> : CollectionTestFixture<T>
  • MyCollectionTests.AsNonGeneric : CollectionTestFixuture

Pros:

  • Can easily run all tests for MyCollection and get overall coverage
  • No additional directories to create and navigate.
  • Common methods can be easily reused by inner classes.
  • Labels read naturally

Cons:

  • Doesn’t work for non-generic enclosing test fixture, but hoping it will work…
The Winner

It is not difficult to conclude that the best implementation is C if NUnit can support it consistently. And IMHO, inner classes are members of enclosing class from the language (logical) perspective although CLR implemented (physical) the other way. I wish test framework implements the logical meaning because that’s what most developers familiar with.

Test Fixture Aggregation

I recall there was a talk about the ability to quickly create a new test fixture by aggregating test cases from multiple reusable test fixtures. The inner class approach is my proposal to the problem. Together with the ability to specify including/excluding of test cases in the inherited fixture may provide a complete solution.

My Wishes

  1. Change NUnit to always consider test cases of inner class as an integral part of the enclosing test fixture. And execute then when the enclosing test fixture is specified to execute.
  2. NUnit-GUI should organize the inner class under the enclosing class in its tree structure.
  3. This one is minor and not important to me but it would be nice if NUnit can hide the implementation detail of CLR and translate to the dot notation for inner class like what the language does.

Tuesday, August 11, 2009

NUnit 2.5.2 Released

The project is very active and Charlie is quite responsive to bug fixes and feature requests. I have recently reported two bugs in one discussion and two feature requests (1, 2). Charlie was able to quickly apply the patch for one bug and implemented the instance of exception assert feature right before 2.5.2 release.

I have heard some good stories of MbUnit as well, it's a mixed feeling to see two open source test framework competing each other. Wouldn't it be nice if they can work together instead of reinventing wheels twice? The combined effort could have produced much more complete test system...

Friday, July 17, 2009

Intercept Explicit Interface Implementation with Inheritance Based Proxy

This is continue from my last post, Intercept Non-Virtual Interface Implementation, Implicit or Explicit.

Krzysztof was absolutely right that it throws MethodAccessException if you just call it. It only works with delegate. But how difficult and/or expensive it is to use delegate?

  1. For each explicit method that we want to intercept, we need to define a new delegate type that matches the method signature
  2. We need to defined a static field of above generated delegate type for each method
  3. Then we use the static delegate instance to make the call to the explicit implementation method in the parent class

This doesn't sound bad to me. There is nearly no runtime CPU overhead, but to hold the generated delegate types, we need some memory. I believe this is well acceptable. After all, we can further optimized it by caching the generated delegate to be reused by the methods with same signature.

I took this as a good opportunity for me to learn the Reflection.Emit API. Thanks to Krzysztof's for the article Working effectively with Reflection.Emit, which led me to the proper tools and approach to start with. Here is what I have achieved.

        public interface IFoo
        {
            void FooMethod(out int i);
            int BarMethod(int i);
        }

        public class Foo : IFoo
        {
            void IFoo.FooMethod(out int i)
            {
                Console.WriteLine("From Foo.FooMethod!");
                i = 100;
            }

            int IFoo.BarMethod(int i)
            {
                return i*i;
            }
        }

        public static void Main(string[] args)
        {
            const string moduleName = "DynamicModule";
            ModuleBuilder mb = EmitUtils.CreateDynamicModule(moduleName);

            Type t = OverrideFoo(mb);

            var proxy = (IFoo) t.GetConstructor(Type.EmptyTypes).Invoke(null);

            int result;
            proxy.FooMethod(out result);
            Console.WriteLine(result);
            Console.WriteLine(proxy.BarMethod(5));
        }

        private static Type OverrideFoo(ModuleBuilder mb)
        {
            TypeBuilder tb = mb.DefineType(
                mb.Assembly.GetName().Name + ".Bar", 
TypeAttributes.Public | TypeAttributes.Class, typeof(Foo), new Type[]{typeof(IFoo)}); var iFooMethods = typeof (IFoo).GetMethods(); var overriders = new List<ExplicitMethodOverrider>(iFooMethods.Length); foreach (MethodInfo iFooMethod in iFooMethods) { overriders.Add(new ExplicitMethodOverrider(mb, tb, iFooMethod)); } Type t = tb.CreateType(); // Initialize static fields for delegates foreach (ExplicitMethodOverrider overrider in overriders) { overrider.InitializeDelegate(t); } return t; }

The output of above program is:

Proxy before call Void DynamicProxy.Program.IFoo.FooMethod(Int32 ByRef)
From Foo.FooMethod!
Proxy after call Void DynamicProxy.Program.IFoo.FooMethod(Int32 ByRef)
100
Proxy before call Int32 DynamicProxy.Program.IFoo.BarMethod(Int32)
Proxy after call Int32 DynamicProxy.Program.IFoo.BarMethod(Int32)
25

The core of this is consisted of two piece of code. One emits the delegate type based on a the MethodInfo of the explicitly implemented base class method. This is done by a static method EmitUtils.GenerateDelegateType, mostly copy from Joel Pobar. Another one emits a static field of delegate type and implement the interface method to call the delegate, which in turn calls the explicit implementation in the base class. This logic is in the the ExplicitMethodOverrider class on which I spent most of my time. The ExplicitMethodOverrider class also provide an initialization method to populate the static field after the type is created.

All the source code can be found here.

Sunday, July 12, 2009

Intercept Non-Virtual Interface Implementation, Implicit or Explicit

Back in April, I blogged about Rhino Mocks' (Castle DP intrinsic) inability to mock non-virtual interface implementation and posted the question in the Rhino Mocks' support group. I didn't receive much feedback until recently, Krzysztof Koźmic killed a good amount of bugs in the DP and so I tried again. What a coincident that Krzysztof also discussed the same issue in his blog 2 days before I sent him the request. :)

Today, the problem is fixed. But Krzysztof also mentioned two limitations. While the 2nd limitation is well understood, I believe there should be a way to overcome the 1st limitation: calling the explicit implementation method in base class.

The problem reminds me of another challenge that I talked about in my post named, C#.Net Calling Grandparent's Virtual Method (base.base in C#). The lesson learned there was that as long as you can get hold of a MethodInfo object, you should be able to emit the call.

I was able to do similar to successfully call the base class explicit implementation method. Code below is to illustration the theory.

    public interface IFoo { void FooMethod(); }

    public class ThirdParty : IFoo
    {
        void IFoo.FooMethod()
        {
            Console.WriteLine("ThirdParty.FooMethod");
        }
    }

    public class Proxy : ThirdParty, IFoo
    {
        private static readonly Action<ThirdParty> baseFooMethod;

        static Proxy()
        {
            var mi = typeof(ThirdParty).GetMethod(
                typeof(IFoo).FullName.Replace('+', '.') + ".FooMethod", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            baseFooMethod = (Action<ThirdParty>) 
                Delegate.CreateDelegate(typeof(Action<ThirdParty>), mi);
        }

        void IFoo.FooMethod()
        {
            Console.WriteLine("Proxy.FooMethod");
            baseFooMethod(this);
        }

        public static void Main(string[] args)
        {
            IFoo foo = new Proxy();
            foo.FooMethod();
        }
    }

I'm not familiar with Emit API enough to write it out so I'll have to leave the rest to DP expert, Krzysztof Koźmic :)

Update 7/17/2009: I was able to implement this, using delegate, with Reflection.Emit. The result was quite good. It is relatively simple, and has minimal runtime CPU performance overhead. See: Intercept Explicit Interface Implementation with Inheritance Based Proxy

Thursday, July 09, 2009

Some Utilities Extend Rhino.Mocks

I have recently blogged a few posts about how to let Rhino Mocks do more for us. They are listed below:

All those features require reader either change the source code of Rhino Mocks or download a special version of Rhino Mocks that I built. Those changes are quite invasive.

By carefully looking at the code, I found that there are some features can be extract into an extension library without touching the Rhino Mocks itself. Actually, only the ordered expectation requires source code change. Hence, I decided to build a extension library so that everybody can use. You can either drop the source into your test project or download the Rhino.Mocks.Extension.dll and add the reference to it.

Here is the current feature list:

  1. Create multi mock for AAA: Mockery.GenerateMultiMock
  2. Create partial mock for AAA: Mockery.GeneratePartialMock, Mocker.GeneratePartialMultiMock
  3. Ability to use test framework's assert: Assert.IsTrue(mock.ActivityOf(x=>x.Foo()));
  4. Use operator to check "or" condition: mock.ActivityOf(x=>x.Foo()) | mock2.ActivityOf(x=>x.Bar())
  5. Support assert for one and exactly one is called: Mockery.ExactOneOf(m.ActivityOf(...), ...).AssertOccured;

Please see my earlier posts for the detail of feature 3-5.

Wednesday, July 08, 2009

Introduce A Powerful AAA Syntax for Rhino.Mocks

I was again (last one was about ordered expectations for AAA) inspired by a question posted on the Rhino Mocks support email group, expect a call to any one of overloaded method. How do we do that? I have proposed a solution and that was pretty much what I did before. When we talk about TDD, we write the test before implementation. And sometimes, designer writes the test cases for somebody else to complete the implementation.

In many cases, all we care is that one of the send methods of the notification service is called. Which exact send method to call is all up to the implementation.

The Syntax

There got to be a better why to do this! The same may not necessary only apply to overloaded methods. For any methods, I should be able to just write something like this:

    ma.AssertWasCalled(a=>a.Foo()) or mb.AssertWasCalled(b=>b.Bar());

The experience gained from my work on the ordered expectation tells me that this is very possible. All I need to figure out is the syntax for this. May be

    ma.AssertWasCalled(a=>a.Foo()).Or(mb.AssertWasCalled(b=>b.Bar()));

or even better to use operator overload:

    ma.AssertWasCalled(a=>a.Foo()) | mb.AssertWasCalled(b=>b.Bar());

Well, the problem is that AssertWasCalled fails right away when a.Foo() is not called. Why do we have to fail it? Why cannot we leave it to the test framework to do the assert? But anyway, in order to not break the existing contract of AssertWasCalled, we'll have to use something different. How about this?

    Assert.IsTrue(ma.ActivityOf(a=>a.Foo()) || mb.ActivityOf(b=>b.Bar()));

Have more methods, not problem!

    Assert.IsTrue(foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything)) || 
        foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything, Arg<Another>.Is.NotNull)) || 
        foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything, Arg<Another>.Is.NotNull, Arg<int>Is.Anything)));

This syntax give us a lot of flexibility. I can use operator overload for ordered expectation as well.

    Assert.IsTrue(ma.ActivityOf(a=>a.Foo()) < mb.ActivityOf(b=>b.Bar()));

And there are unlimited possibilities, some examples below:

    // chained ordering
(m.ActivityOf(...) > m.ActivityOf(...) > m.ActivityOf(...)).AssertOccured;
    // mixed or ordering
(m.ActivityOf(...) | m.ActivityOf(...)) < m.ActivityOf(...)).AssertOccured
    var sent = (m.ActivityOf(a=>a.Sent(x)) | m.ActivityOf(a=>a.Sent(x, y)));
    Assert.IsTrue(sent); // assert sent is called
    Assert.IsTrue(sent < m.ActivityOf(a=>a.Close())); // assert sent called before close

Implementation

This is exciting, isn't it? How difficult to implement this? I give it a try by building on top of the changes that I made for the ordered expectation in the previous post. It turn out to be quite easy. Although the code below is no where close to perfect, and indeed it is quick and dirty to some extend, but it served well as proof of concept to introduce this technique.

Here we go the code. The Activities class is the core. It provides implementation for all the operator overload.

    public class Activities : IComparable<Activities>
    {
        private static readonly CallRecord[] _emptyRecords = new CallRecord[0];
        private readonly IList<CallRecord> _callRecords = _emptyRecords;
        private readonly ExpectationViolationException _exception;

        public Activities(IList<CallRecord> callRecords)
        {
            if (callRecords == null || callRecords.Count == 0)
                throw new ArgumentException(
                    "Must not be null or empty.", "callRecords");
            _callRecords = callRecords;
        }

        public Activities(ExpectationViolationException exception)
        {
            if(exception==null) throw new ArgumentNullException("exception");
            _exception = exception;
        }

        public bool Occured
        {
            get { return _callRecords.Count > 0; }
        }

        public Activities OccuredBefore(Activities other)
        {
            if (!Occured) return this;
            if (!other.Occured) return other;

            var thisLast = GetLast();
            CallRecord otherFirst = other._callRecords[0];

            return thisLast.Sequence < otherFirst.Sequence ? other
                : new Activities(NewOrderException(thisLast, otherFirst));
        }

        private ExpectationViolationException NewOrderException(
            CallRecord before, CallRecord after)
        {
            return new ExpectationViolationException(
                "Expected that call " + before.Method +
                " occurs before call " + after.Method +
                ", but the expectation is not satisfied.");
        }

        public Activities OccuredAfter(Activities other)
        {
            if (!Occured) return this;
            if (!other.Occured) return other;

            CallRecord otherLast = other.GetLast();
            CallRecord thisFirst = _callRecords[0];
            return otherLast.Sequence < thisFirst.Sequence ? other
                : new Activities(NewOrderException(otherLast, thisFirst));
        }

        public Activities Or(Activities other)
        {
            if (Occured) return this;
            if (other.Occured) return other;
            return new Activities(new ExpectationViolationException(
                this._exception.Message + "\nor\n" + other._exception.Message));
        }

        public Activities First {
            get {
                return Occured ? new Activities(new CallRecord[] {_callRecords[0]}) : this;
            }
        }

        public Activities Last {
            get {
                return Occured ? new Activities(new CallRecord[] { GetLast() }) : this;
            }
        }

        private CallRecord GetLast()
        {
            return _callRecords[_callRecords.Count - 1];
        }

        public int CompareTo(Activities other)
        {
            if (ReferenceEquals(this, other)) return 0;
            return OccuredBefore(other) ? -1 : 1;
        }

        public static implicit operator bool(Activities activities)
        {
            return activities.Occured;
        }

        public static Activities operator <(Activities a1, Activities a2)
        {
            return a1.OccuredBefore(a2);
        }

        public static Activities operator >(Activities a1, Activities a2)
        {
            return a1.OccuredAfter(a2);
        }

        public static Activities operator |(Activities a1, Activities a2)
        {
            return a1.Or(a2);
        }

        public static Activities operator ^(Activities a1, Activities a2)
        {
            return OneOf(a1, a2);
        }

        public static bool operator true(Activities a)
        {
            return a.Occured;
        }

        public static bool operator false(Activities a)
        {
            return !a.Occured;
        }

        public void AssertOccured()
        {
            if (_exception != null) throw _exception;
        }

        internal static Activities ExactOneOf(params Activities[] activitiesList)
        {
            Activities one = null;

            foreach (var activities in activitiesList)
            {
                if (!activities.Occured) continue;
                if (one == null) one = activities;
                else
                    return new Activities(
                        new ExpectationViolationException(
                            "Both " + one._callRecords[0].Method +
                            " and " + activities._callRecords[0].Method +
                            " was called"));
            }
            if (one != null) return one;

            StringBuilder sb = new StringBuilder("None of below is satisfied:");
            foreach (var activities in activitiesList)
            {
                sb.Append('\n').Append(activities._exception.Message);
            }
            return new Activities(new ExpectationViolationException(sb.ToString()));
        }
    }

The other class holds a few extension methods that glues this new API to existing Rhino Mocks.

    public static class Mockery
    {
        public static Activities ActivityOf<T>(this T mock, Action<T> action, 
            Action<IMethodOptions<object>> setupConstraints)
        {
            try
            {
                return new Activities(mock.AssertWasCalled(action, setupConstraints));
            }
            catch (ExpectationViolationException e)
            {
                return new Activities(e);
            }
        }

        public static Activities ActivityOf<T>(this T mock, Action<T> action)
        {
            return ActivityOf(mock, action, DefaultConstraintSetup);
        }

        public static Activities ActivityOf<T>(this T mock, Function<T, object> func, 
            Action<IMethodOptions<object>> setupConstraints)
        {
            return ActivityOf(mock, new Action<T>(t => func(t)), setupConstraints);
        }

        public static Activities ActivityOf<T>(this T mock, Function<T, object> func)
        {
            return ActivityOf(mock, func, DefaultConstraintSetup);
        }

        public static void Assert(Activities activities)
        {
            activities.AssertOccured();
        }

        public static Activities ExactOneOf(params Activities[] activitiesList)
        {
            return Activities.ExactOneOf(activitiesList);
        }

        private static void DefaultConstraintSetup(IMethodOptions<object> options)
        {
        }
    }

You can see that the implementation of the first ActivityOf method is very quick and dirty. The idea was to keep this POC code simple enough to illustrate the technique.

The Failure Message

There is one minor issue with using test framework's Assert.IsTrue. When the assert fails, it simply tells you that you expected true but got false. I don't see this as a big issue because with today's tool you can easily click on the error to jump to the exact line of code. In most of time, the code gives much more information then the message itself. But hey, it is always good to have detailed message right?

Careful reader must already found the Assert method in the Mockery class, that is the one used to replace the Assert.IsTrue. It provides "better" message then true/false. The reason for the quotation marks around the word better is that at this moment, the implementation can sometime provide ambiguous message. Again this is just a POC, in order to provide accurate message, we will need to make deeper changes into the Rhino Mocks.

Below are some examples from the unit test:

            Mockery.Assert(mb.ActivityOf(b => b.Bar()).First
                .OccuredBefore(ma.ActivityOf(a => a.Act()).First)
                .OccuredBefore(mb.ActivityOf(b => b.Bar()).Last));

            (mb.ActivityOf(b => b.Bar()).First
                < ma.ActivityOf(a => a.Act()).First
                < mb.ActivityOf(b => b.Bar()).Last).AssertOccured();
            Mockery.Assert(foo.ActivityOf(f => f.Foo(1)) | 
                foo.ActivityOf(f => f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything)));

            (foo.ActivityOf(f => f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything)) | 
                foo.ActivityOf(f => f.Foo(1))).AssertOccured();

C# 2.0 / VS2005 Support

It was said that the AAA for C# 2.0 is ugly and tedious. I tried to using this new API with C# 2.0 syntax. The result is not too bad at all. Let's take a look at what we have in the unit test cases:

            Mockery.Assert(Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).Last
                .OccuredAfter(Mockery.ActivityOf(mb , delegate(IB b) { b.Bar(); }).Last)
                .OccuredAfter(Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).First));

            (Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).Last
                > Mockery.ActivityOf(mb, delegate(IB b) { b.Bar(); }).Last
                > Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).First).AssertOccured();

            Mockery.Assert(
Mockery.ActivityOf(foo, delegate(IFoo f) { f.Foo(1); }) | Mockery.ActivityOf(foo, delegate(IFoo f) { f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything); }));

Give It A Try

If you want to give it a try, I have build a version of Rhino Mocks based on last trunk source with the latest Castle DynamicProxy2 at this moment. You can find them here:

http://code.google.com/p/kennethxublogsource/downloads/list

There are also other features in the build like:

  • Create multi mock for AAA: Mockery.GenerateMultiMock
  • Create partial mock for AAA: Mockery.GeneratePartialMock and Mocker.GeneratePartialMultiMock

Update (7/9/2009): For people don't want a modified version of Rhino.Mocks, I have made an extension library without the feature of ordered expectation: Some Utilities Extend Rhino.Mocks

Saturday, June 27, 2009

Rhino.Mocks Ordered Expectations Enhanced API for AAA

In my last post, I proposed a way, an affordable way, to have Rhino.Mocks support ordered expectations in AAA syntax. I introduced one extension method Before. Actually, with that ground work, we can quickly add more ordering related extension methods. Let's take a look at same asserts in the test case to see what are possible.

            mockBefore.AssertWasCalled(b => b.MethodBefore())
                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));

            mockAfter.AssertWasCalled(a => a.MethodAfter())
                .After(mockBefore.AssertWasCalled(b => b.MethodBefore()));
 
            mockBefore.AssertWasCalled(b => b.MethodBefore()).First()
                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()).First())
                .Before(mockBefore.AssertWasCalled(b => b.MethodBefore()).Last());

            mockAfter.AssertWasCalled(a => a.MethodAfter()).Last()
                .After(mockBefore.AssertWasCalled(b => b.MethodBefore()).Last())
                .After(mockAfter.AssertWasCalled(a=>a.MethodAfter()).First());

With the enhanced API, you can

  • Chain multiple Before and After calls, even mix the Before and After.
  • When a method is called multiple times, you can specify if the expectation should apply the first call or last call.

And below are how they are implemented.

        /// <summary>
        /// Assert that all calls specified by <paramref name="beforeCalls"/> 
        /// occurred before all calls specified by <paramref name="afterCalls"/>
        /// </summary>
        /// <param name="beforeCalls">
        /// Calls that happens before <paramref name="afterCalls"/>
        /// </param>
        /// <param name="afterCalls">
        /// Calls that happens after <paramref name="beforeCalls"/>
        /// </param>
        public static IList<CallRecord> Before(this IList<CallRecord> beforeCalls, IList<CallRecord> afterCalls)
        {
            Ordered(Last(beforeCalls), First(afterCalls));
            return afterCalls;
        }

        /// <summary>
        /// Assert that all calls specified by <paramref name="afterCalls"/> 
        /// occurred after all calls specified by <paramref name="beforeCalls"/>
        /// </summary>
        /// <param name="afterCalls">
        /// Calls that happens after <paramref name="beforeCalls"/>
        /// </param>
        /// <param name="beforeCalls">
        /// Calls that happens before <paramref name="afterCalls"/>
        /// </param>
        public static IList<CallRecord> After(this IList<CallRecord> afterCalls, IList<CallRecord> beforeCalls)
        {
            Ordered(Last(beforeCalls), First(afterCalls));
            return beforeCalls;
        }

        /// <summary>
        /// Assert that the call specified by <paramref name="before"/> 
        /// occurred before the call specified by <paramref name="after"/>
        /// </summary>
        /// <param name="before">
        /// Call that occurred before <paramref name="after"/>
        /// </param>
        /// <param name="after">
        /// Call that occurred after <paramref name="before"/>
        /// </param>
        public static CallRecord Before(this CallRecord before, CallRecord after)
        {
            Ordered(before, after);
            return after;
        }

        /// <summary>
        /// Assert that the call specified by <paramref name="after"/> 
        /// occurred after the call specified by <paramref name="before"/>
        /// </summary>
        /// <param name="after">
        /// Call that occurred after <paramref name="before"/>
        /// </param>
        /// <param name="before">
        /// Call that occurred before <paramref name="after"/>
        /// </param>
        public static CallRecord After(this CallRecord after, CallRecord before)
        {
            Ordered(before, after);
            return before;
        }

        /// <summary>
        /// Returns the last executed call in the <paramref name="callRecords"/>.
        /// </summary>
        /// <param name="callRecords">
        /// A list of call records ordered by the time they were executed.
        /// </param>
        /// <returns>The last call executed in <paramref name="callRecords"/></returns>
        public static CallRecord Last(this IList<CallRecord> callRecords)
        {
            return callRecords[callRecords.Count - 1];
        }

        /// <summary>
        /// Returns the first executed call in the <paramref name="callRecords"/>.
        /// </summary>
        /// <param name="callRecords">
        /// A list of call records ordered by the time they were executed.
        /// </param>
        /// <returns>The first call executed in <paramref name="callRecords"/></returns>
        public static CallRecord First(this IList<CallRecord> callRecords)
        {
            return callRecords[0];
        }

    private static void Ordered(CallRecord before, CallRecord after)
    {
        if (before.Sequence > after.Sequence)
        {
            throw new ExpectationViolationException(
                "Expected that call " + before.Method +
                " occurs before call " + after.Method +
                ", but the expectation is not satisfied.");

        }
    }