Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax - ISerializable - Roy Osherove's Blog

Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

As I was looking back and forward on the changing syntax of testing and mock frameworks, it occurs to me that there are still things that need to be solved in the mocking space. many things.

  • It's hard to choose a framework and stick with it because they have different abilities which you are not sure you might need or not later on
  • Each framework has different syntax which is a learning curve and maintainable curve in test code
  • You can't change your mind easily after you choose
  • There is no specified set of known features to be expected. Each one has what it thinks is best.

 

What if we had an abstract layer on top of our mocking frameworks? Just like ADO.NET is an abstraction layer, and the Data Application block is an abstraction layer, NHibernate is an abstraction layer - Mocking frameworks are infrastructure libraries that, if looked at well enough, are pretty much trying to do the same things in different ways (like databases)

 

Here are the main services a mocking framework can provide(if I miss something tell me):

o   Stubs

§  Create Canned Answers

o   Mocks

§  Create Expectations

·         Record-Replay Model

·         Explicit Model

·         Parameter Constraints

·         Custom param constraints

§  Partially Implemented Mocks

§  Pass-through mocks

§  Strict\non strict

§  IoC- Auto mocking containers

o   Mocking Abilities

§  Strict (Traditional Interface based)

§  Non Strict (Typemock,JMockit Stuff)

 

There are two main services here: Expectation abilities, and Creation\Isolation abilities.

what if there was a framework that would allow you to write code like this:

 [Test]
        public void CreateSimpleInterfaceBasedMock()
        {
            MockingEngine.Provider = new RhinoMocksProvider();
            IMock<ILogger> mockLogger =
                Represent.Type<ILogger>().AsMock();
        ...

        }

 

What would the proposed AEIS (Abstract Expectation and Isolation Syntax) look like?

image

I would consist of a very thin API wrapper that allowed all the different services mocking frameworks do today, but it would not do this functionality on its own. instead it would use a provider model that will allow one to write adapters for specific mocking frameworks, forwarding calls and translating the different syntaxes between AEIS and the specific framework. I will also have a rules engine (on the left) that will allow creating custom rules that will run when using various APIs (perhaps using an event driven relay) that will allow to enforce specific usage of specific features.

 

what would be some of the benefits in something like this?

You can change mocking frameworks without changing lots of code

There is an investment to be made when choosing a mocking framework today: You spend time learning the syntax, you write tests with that syntax and you plan on not learning a new syntax to do slightly different things. A year later mock framework X comes in and you think that you'd like to use it, but you've already invested so much time and money in the original one that you aren't going to try. You lose valuable features just to avoid the risks.

You can add rules “on top” of the mocking framework

An abstraction layer can have custom code that will allow you to write custom logic that makes sure developers are using the framework in a way that you'd like. for example, you'd like to use Typemock Isolator but you are afraid that people will abuse the ability to write tests for code that isn't "testable" by default (no interfaces etc..)

I call that"Strict" mocking policy vs. "loose" mocking policy (or "classic\traditional vs. modern..."). So the 
        o    Allow only strict mocking syntax, for example


One syntax to remember and learn for all types of jobs

Simplify and overcome problematic mocking syntax in existing frameworks

And there are definitely some around. For example, Typemock Isolator currently has a very confusing Mock() and MockObject() set of methods which sometimes I personally forget what each one does. Sure, we'll change it, but RhinoMocks also has some confusing syntax (PartialMocks() vs. DynamicMock() Vs. Mock()...)

Having a top level API can help alleviate and standardize some of these issues.

Provide a recipe for mock framework builders

If you have to build a provider for your mocking framework, you have to have a contract of what you can and cannot provide. this will also help standardize the essential set of services that mocking frameworks provide today or at least, the set of things you need to consider when choosing among them as the underlying engine.

It will help avoid religious wars (like design for testability) by allowing you to choose easily and enforce to your standards through the common API.

 

What about testing frameworks? why not start there?

I think currently most test frameworks (XUnit.net aside) are pretty much interchangeable (Nunit and MbUnit and msTest) so there is less pain there. However, take a look at the next version of MbUnit ,  running on the Gallio automation platform) which tries to provide a generic test runner model for all test frameworks in .net. I think they are trying to solve the same set of pains and the same set of benefits.

Published Thursday, February 14, 2008 6:10 PM by RoyOsherove

Comments

Thursday, February 14, 2008 8:55 PM by Nick

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Ditto for IoC containers.

It would be great to see more collaboration between independent .NET projects with similar goals.

Creating open standards like this might encourage more of the 'healthy diversity' that you see in the Java space, rather than the current situation where we wait for Microsoft to set the standard by including something in the BCL...

Not that the task would be without its challenges... ;)

Friday, February 15, 2008 2:57 AM by Casey

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Now that I like the idea of!

Mock syntax for all all frameworks is one of my general bugbears ... it isn't only frequently convoluted  ... but the dependency you place within your tests upon the mock framework you choose is something you can later come to regret.

Friday, February 15, 2008 3:16 AM by Symon Rottem

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Interesting idea.  The team I'm working with at the moment are trying to get their heads around mocking and choose a container but they don't know enough about each one to make an informed choice.  The result is that they may very well make the wrong choice and have a lot of work to migrate from one to another or even find themselves using more than one (where they need to learn another syntax and/or approach).  Having an abstraction that standardizes would certainly help reduce the problem for newcomers.

Friday, February 15, 2008 4:25 AM by Andy Stopford

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Hi Roy,

In terms of unit test frameworks, MbUnit and NUnit can be interchanged (with the current exception of NUnit constriants) at will but although MSTest has some common ground with asserts the attributes are not the same.

Your correct to point out Gallio and how this is going to provide a common model for all test frameworks but it is worth noting the NUnit teams own direction on this front. Take a look at

http://nunit.com/blogs/?p=53

Friday, February 15, 2008 5:18 AM by Thomas Eyde

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

This is a little off-topic, but your listed services misses something I need. Or think I need.

My root-cause is that almost all of my mock-based tests ends up to be tightly coupled to implementation, which makes refactoring hard. I have yet to find out why this happens.

One typical scenario would be the testing of WebForms. The WebForm will be mocked, as will my services/tasks. The Presenter will be under test.

Here's what I usually do: I let the WebForm/mock provide strings, while the service expects objects. The Presenter will then need to create the objects from the strings, however, I consider this an implementation detail. My tests are not concerned about how it's done, just that it is done. How do I test that?

My answer to that question have been to handwrite my mock (or is it a stub?), then ask my mock for the passed object and assert for expected information.

In this way, I can change my implementation without touching the tests. I can let the Presenter do the job, or delegate it to some factory/mapper. If I later need to refactor those helpers, I can do that too.

Which means I'd like to query my mocks for passed information, but I haven't found out how to do that with the usual frameworks.

I suspect that isn't your way, and that you have solved this problem. How do you do it?

Friday, February 15, 2008 6:48 AM by Ayende Rahien

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Thomas,

In Rhino Mocks, looks for the Do() method. It allows you to do that.

Roy,

This is an interesting idea, but it has one problem. The mocking frameworks that you mentioned has wildly different model for use.

Rhino Mocks uses the record / replay model and is strongly typed, NMock uses expectation as string.

How are you going to create an API that would encompass them both?

Friday, February 15, 2008 7:03 AM by RoyOsherove

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Oren: That's the point - The AEIS API should allow , in my mind, either both abilities or just one of them. underneath it will translate them to the standard calls for the frameworks (like LINQ does)

Friday, February 15, 2008 7:28 AM by Eli Lopian

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Thomas,

In Typemock Isolator, you can use the DynamicReturnValue or Conditional Return Values

Roy,

This sounds like a good idea, I wonder if it is feasible :-)

Friday, February 15, 2008 9:54 AM by peter ritchie

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

I think an idea like this would go a long way, not only toward increase use of mocking; but towards better decoupling of mocking "frameworks" from unit testing frameworks.  Let's be honest, a mocking framework depends upon a unit testing framework.  If you can't view your mocking framework abstractly from your unit testing framework you can't be as flexible as you need to be.

I think ideas like this should proliferate throughout all the Agile frameworks: mocking, unit testing, code coverage, IoC, etc.  Once we can build our own stack as easy as using one of the pre-built stacks the better life will be.

Friday, February 15, 2008 1:24 PM by Stefan Lieser

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

I've started to take a deeper look into TypeMock and I'm missing Rhino's fluent interface:

// TypeMock

expectations.ExpectAndReturn(customer.Orders, new Order[] { order });

// Rhino.Mocks

Expect.Call(customer.Orders).Return(new Order[] { order });

I like Rhino's fluent interface because of the typesafety and because ReSharper can help me a lot more filling in the .Return(...) parameter.

So my question is: do I miss something or doesn't TypeMock have such a fluent interface?

Regards,

Stefan Lieser

Friday, February 15, 2008 1:26 PM by Charlie

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

As I said in my note, I think you may underestimate the degree of attachment that mock users have to their syntax. :-)

Nevertheless, I hope it can work and I'll commit to including AEIS in NUnit distributions if the licensing permits it.

Charlie

Friday, February 15, 2008 2:48 PM by Jeff Brown

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

AEIS sounds pretty interesting.  I'm worried it might gloss over some of the valuable differentiating factors among mock object frameworks.

Ultimately its success will depend on whether AEIS takes a union or intersection approach to its API.

Union: AEIS tries to support everything all of the frameworks can do.  The downside is that the user loses the built-in constraints that indicate when a framework cannot do something in particular.  It's unclear what would happen if one attempted to use unsupported constructs within a test.

Intersection: AEIS only supports common features among all frameworks.  The downside is that the user can no longer access certain fancy/more powerful capabilities only offered by one framework or another.

I'd also be somewhat concerned about limiting the ability of mock object framework providers to innovate wrt. syntax.

As an aside, I've also been thinking about providing a common instrumentation framework that would plug into Gallio.

It would provide basic services for profiling, dynamic proxies, performance measurement, adaptive load generation, and real-time monitoring services.

The idea here would be to provide a common infrastructure for a variety of tools that require additional hooks into the runtime for interception, data collection, analysis and reporting purposes.

Imagine defining a common means of capturing data traces for performance analysis.  Any number of performance data providers could then  record measurements during test execution (or authoring, perhaps).  This data might end up inside test reports or in a data warehouse of some kind.

Just thinking out loud.

Friday, February 15, 2008 5:41 PM by Jeremy Gray

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

-1.

Why are we, as technologists, always so inclined to preach about the benefits of diversity yet so often work to eliminate that diversity instead of allowing things to play out naturally? The syntax, which this post aims to see normalized, _is_ what makes the various mock frameworks different in the minds of those that use them. Attempting to unify these syntaxes can only serve to neuter them and their implementations.

Friday, February 15, 2008 5:43 PM by Jeremy Gray

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

To "peter ritchie" - I'm not sure what mocking framework you are using, Peter, but the one that I am using is most certainly not tied to any unit testing framework.

Friday, February 15, 2008 7:26 PM by RoyOsherove

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Jeff: I'd be leaning more towards the Union idea, with the engine adapters implementing specialied ISupports interfaces that return true false to various features. so, for example mocking static methods, AEIS will ask the provider before each test run whether it supports the features that are used in this API and throw if it does not (even better, try to automatically find and load the provider that does support them!)

Saturday, February 16, 2008 2:28 AM by Eli Lopian

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

Stefan Lieser, you should you TypeMocks NaturalMocks for typesafe and mocking a chain of calls.

using (RecordExpectation r = new RecordExpectation ())

{

  Factory.GetCustomer().Orders();

   r.Return(fakeOrders);

}

Saturday, February 16, 2008 2:36 AM by Jeff Brown

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

The problem with ISupports and throwing at runtime is that it is then not clear to the test author that what's been written won't work.  Until runtime.

Most frameworks include numerous constraints built into the syntax to guide their use.  Although they certainly don't prevent anyone from writing things that won't work...  =)

Saturday, February 16, 2008 1:31 PM by James

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

This has already been proposed in the Java community: www.mockobjects.com/.../announcing-commonstesting-and.html.  And also for .NET: ayende.com/.../Microsoft-Enterprise-Mocking-Block.aspx.

Saturday, February 16, 2008 3:56 PM by RoyOsherove

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

James: Ayende's blog post is an april's fool's joke (just look at the code)

The same is true for the java post.

Monday, February 18, 2008 12:38 AM by Finds of the Week - February 17, 2008 » Chinh Do

# Finds of the Week - February 17, 2008 &raquo; Chinh Do

Pingback from  Finds of the Week - February 17, 2008 &raquo; Chinh Do

Wednesday, March 05, 2008 1:24 PM by JH

# re: Future of Mock Frameworks: AEIS - Abstract Expectations & Isolation Syntax

I would think that this proposed solution would end up with a fate similar to SvnBridge that Oren has been talking about. Some of the symantics of the different mocking frameworks just aren't that easily bridge-able. Good concept though.