Chains, Part I: Chain-Challenged

Chains are difficult to grasp, to develop and to understand. And some of them are even hidden, and therefore are not so easy to identify. So, what are they and what have they done to deserve a couple of blog post? Apparently it’s a complicated feature to master from both the developer and user perspective. So I thought I’ll clear the topic, top to bottom, until I, I mean WE, understand it better.

What are chains?

We use the term “chain” to describe a set of chained calls, where the return value of one method is the target where the next method is invoked on. And since describing it in words is to confusing enough, consider this simple chain:

int x = a.b().c();

As any compiler knows, this is equivalent to:

SomeClass temp1 = a.b();
int x = temp1.c();

And chains can be nested, as can be seen in the following simple example:

int x = a.b().c(d.e(f.g().h(2,i.j()));

Chains in Natural Mocks

Setting an expectation on a chain, originally meant setting it on the last call. Basically we don’t care about the rest of the chains, and setting expectations on the beginning or middle doesn’t matter for the test. But it’s a bit more complicated. One of the new features in Typemock Isolator 4.2 clears a semantic issue. The Repeat and RepeatAlways methods now refer to the entire chain. For example:

using (RecordExpectations rec = RecorderManager.StartRecording())
{
 int x = a.b().c();
 rec.Return(5).RepeatAlways();
}

int t = a.b().c();  //returns 5
int s = new SomeClass().c(); // is not mocked, and returns its original value
That’s a break from the former behavior (pre 4.2), when the expectation was set only on the c() method. This change, by the way, came from feedback we received from the community, and we were happy to oblige.

The Missing LINQ

How’s LINQ connected to chains? (yes, some pun IS intended). Well, when the compiler parses LINQ queries, it creates a long chain of calls, full of expression, expression trees and other vegetation, which compile to chains and nested chains. So when someone tries to mock a LINQ query, they get a lot of confusing error messages. The error comes from the current implementation which handles nested chains sub-optimally. More on this later.

The Next Chain Chapter

So we are working on a fix for the LINQ problem. My next post will be about the how Isolator interprets chains, the pitfalls, and how we are progressing on the path to resolution. Which, by they way is full of fun.

TOP