Easy + Scalable + Affordable

UNIT TESTING HORROR STORIES – SHARE YOURS NOW!

 

Yeah, we know unit testing is not always easy.

With over 50,000 Typemock users worldwide, we’ve heard it all before: crazy deadlines, pesky bugs and difficult bosses. But we also know that when you stick to it – it’s all worthwhile!

We want to hear your unit testing horror story, whether you succeed or not, so others can learn from your experience and better cope with the difficulties of getting there. And let’s face it – it’s always amusing to hear about it!

Post your story on our special Unit Testing Horror Stories webpage (via the Facebook “comments” plug-in, so you’ll need to be logged in).

If you don’t have a Facebook account, you can email your story to: social@typemock.com, and we’ll post it on your behalf.

Our team of experts will pick the best ones, and award their contributors with some great prizes, and a chance to become one of our Unit Testing Evangelist.

Hurry up! Entries accepted until Tuesday April 30.

 

 

What would YOU DoInstead? The Sequel

So last time, I showed you how to do something before a method is called. That’s nice but what if you want to do something after it’s called?

Let’s look again at the code under test:

   1: public class UserManager

   2: {

   3:     string prefix = "pre";

   4:     string suffix = "suff";

   5:  

   6:     static public int LogInCount = 0;

   7:     public bool CanUserLogIn(string user)

   8:     {

   9:         return Authenticate(prefix, user, suffix);

  10:     }

  11:  

  12:     private bool Authenticate(string prefix, string user, string suffix)

  13:     {

  14:         string fullUserName = prefix + user + suffix;

  15:         return Authenticate(fullUserName);

  16:     }

  17:  

  18:     private bool Authenticate(string fullUserName)

  19:     {

  20:         bool result = Authenticator.IsUserAuthorized(fullUserName);

  21:         if (result)

  22:             LogInCount++;

  23:         return result;

  24:     }

  25: }

 

The API we used in our last venture is:

callContext.WillCallOriginal();

As you probably can guess, it’s the part that tells Isolator to run the original code. We didn’t call it in the future tense, though. The method will be executed after the code in the DoInstead clause is completed.

In our next case, we want the Authenticate overload with 1 parameter to also run. But we want to log (and maybe even assert) the static variable LogInCounter.

Now, we need a way to tell Isolator to invoke the method, and continue running. Let’s take a look at this test:

 

   1: [TestMethod]

   2: public void CanUserLogIn_2ndAuthenticateCalls_LoggingBeforeAndAfter()

   3: {

   4:     UserManager manager = new UserManager();

   5:  

   6:     Isolate.NonPublic.WhenCalled(manager, "Authenticate").DoInstead(

   7:         callContext =>

   8:         {

   9:             if (callContext.Parameters.Length == 3)

  10:             {

  11:                 callContext.WillCallOriginal();

  12:             }

  13:             if (callContext.Parameters.Length == 1)

  14:             {

  15:                 Console.WriteLine(@"LogInCount Before : {0}", UserManager.LogInCount);

  16:                 callContext.Method.Invoke(callContext.Instance, new object[] { callContext.Parameters[0] });

  17:                 Console.WriteLine(@"LogInCount After: {0}", UserManager.LogInCount);

  18:             }

  19:             return true;

  20:         });

  21:  

  22:     Assert.IsTrue(manager.CanUserLogIn("Valid"));

  23: }

We see that if we call the Authenticate with 3 arguments, it will be executed once the DoInstead clause completes.

However, when the overload with 1 argument we use another option. CallContext.Method contains the metadata of the method that’s being called. With that metadata, we can invoke it before the DoInstead completes. And we can do something after the method.

We know that the definitive AOP example is logging. Is it useful to more than that in a testing context?

Imagine that the Authenticator.IsUserAuthorized method might crash the system sometime. Or leave the system unclean. For our purpose, we want to run it as-is and not mock it, but when it crashes we don’t want to ruin it for the other tests.

In this case we can do something like this:

 

   1: [TestMethod]

   2: public void CanUserLogIn_AuthenticatorCalled_WithCleanUp()

   3: {

   4:     UserManager manager = new UserManager();

   5:  

   6:     Isolate.WhenCalled(() => Authenticator.IsUserAuthorized("")).

   7:         DoInstead((callContext) =>

   8:         {

   9:             try

  10:             {

  11:                 callContext.Method.Invoke(null, new object[] { callContext.Parameters[0] });

  12:             }

  13:             catch (Exception e)

  14:             {

  15:                 // do some error handling

  16:             }

  17:             finally

  18:             {

  19:                 // do some clean up

  20:             }

  21:             return true;

  22:  

  23:         });

  24:     Assert.IsTrue(manager.CanUserLogIn("Valid"));

  25: }

 

When the method IsUserAuthorized is called, we run it inside a try-catch-finally block, which allows us to the recovery and clean up we need when going to the next test.

What other AOP functionalities did you ever wished you had while testing?

What would YOU DoInstead?

I often describe DoInstead as the 10lb/kg hammer to change behavior – if all fails, and any other API doesn’t help use it.

I want to give you a couple of examples on different occasions where using DoInstead can be helpful, above and beyond the call of duty. Let’s start with the class we’ll work on. This class is called UserManager and handles log-ins.

 

   1: public class UserManager

   2: {

   3:     string prefix = "pre";

   4:     string suffix = "suff";

   5:  

   6:     

   7:     public bool CanUserLogIn(string user)

   8:     {

   9:         return Authenticate(prefix, user, suffix);

  10:     }

  11:  

  12:     private bool Authenticate(string prefix, string user, string suffix)

  13:     {

  14:         string fullUserName = prefix + user + suffix;

  15:         return Authenticate(fullUserName);

  16:     }

  17:  

  18:     private bool Authenticate(string fullUserName)

  19:     {

  20:         bool result = Authenticator.IsUserAuthorized(fullUserName);

  21:         

  22:             

  23:         return result;

  24:     }

  25: }

As you can see, it has an overloaded Authenticate private method, both called by the public method.

For our first test, I’d like to call the real Authenticate method with the 3 arguments, but fake the internal with the single argument.Not that if the methods were’ public, this wans’t a real issue, since the public API lets you specify the exact overload. With non-public methods, we need to get creative.

 

   1: [TestMethod]

   2: public void CanUserLogIn_2ndAuthenticateCallFaked()

   3: {

   4:     UserManager manager = new UserManager();

   5:  

   6:     Isolate.NonPublic.WhenCalled(manager, "Authenticate").DoInstead(

   7:         callContext =>

   8:         {

   9:             if (callContext.Parameters.Length == 3)

  10:             {

  11:                 callContext.WillCallOriginal();

  12:                 return true;

  13:             }

  14:             return false;

  15:         });

  16:  

  17:     Assert.IsFalse(manager.CanUserLogIn("Invalid"));

  18: }

Since we’re dealing with non-public methods here, so I’m using the Isolate.NonPublic APIs. In the DoInstead clause, we can check the number of parameters. If the number of parameters is 3, we’ll call the original method. Otherwise, we’ll just return a fake false value.

What’s that WillCallOriginal thingy? It’s a new API we’ve added in Isolator version 7.3. It allows you to specify that once the DoInstead code runs, it will continue to run the original method. The return statement that follows is required for syntactic reasons, and in our case doesn’t really change anything. Don’t believe me? Debug it!

Ok, don’t. See if I care.

Let me show you another test to show that it actually works:

   1: [TestMethod]

   2: public void CanUserLogIn_BothCallsAreReal_LoggingBefore()

   3: {

   4:     UserManager manager = new UserManager();

   5:  

   6:     Isolate.NonPublic.WhenCalled(manager, "Authenticate").DoInstead(

   7:         callContext =>

   8:         {

   9:             if (callContext.Parameters.Length == 3)

  10:             {

  11:                 Console.WriteLine(@"Prefix: {0}, Suffix: {1}: , User: {2}", 

  12:                     callContext.Parameters[0], callContext.Parameters[2], callContext.Parameters[1]);

  13:             }

  14:             if (callContext.Parameters.Length == 1)

  15:             {

  16:                 Console.WriteLine(@"Full Name: {0}", callContext.Parameters[0]);

  17:             }

  18:             callContext.WillCallOriginal();

  19:             return true;

  20:         });

  21:  

  22:     Assert.IsTrue(manager.CanUserLogIn("Valid"));

  23: }

 

This time, we’re not faking anything. But we’ve added some logging just before the actual methods run. It’s a different method of logging, since each overload looks different. Using DoInstead here doesn’t have any impact on the test, but it helps if you need some logging magic.

It’s a bit like AOP, isn’t it? Injecting code before the actual method runs.

But what if we need to inject code after the method runs?

Wait for the next post to find out…

 

Gil Zilberfeld

Isolator 7.3 Released!

 

It’s been a while now. And we have good reasons. Some of you already know: Microsoft issued an update, and suddenly all your tests are failing. Ours too, by the way.

Most of our work recently was directed at resolving this issue. And thanks to your patience and feedback, we’ve got this resolved. Isolator 7.3 is all about that.

…and other stuff as well.

With Isolator 7.3 we’ve got a better, faster, smarter runner. The feedback we got helped us build a better UI, replacing the ol’ dashboard with a new Test Navigator window. No more blocking the view. We’ve added some performance enhancements and support for MS-Test deployment items. We got features we discovered we need, such as a re-debug last test short cut. Very useful productive stuff.

UIIt’s not perfect, but like the New  Kids On The Block have said before me: Step by step.

We’ve got some new APIs requested by customers, like Isolate.NonPublic.WhenCalled(…).AssignRefOut(…) which (wait for it…) helps with faking non-public methods with ref and out parameters.

We also added a new set of APIs for future objects, trying to clear out some confusion that was there from the beginning: Isolate.Fake.NextInstance and Isolate.Fake.AllInstances are the way to go from now on. We kept the old Isolatoe.Swap APIs for backward compatibility, but these feel clearer to us – what do you think?

We’ve got also more fixes, better performance and stability. One pesky one is the (returned) ability to actually set the next statement while debugging when mocking is enabled. Welcome back, we’ve missed you!

We also have improved integration with NCrunch. Plus VS 2012 coverage linking is now implicit – you don’t need to go through the manual linking, it just works out of the grey box.

I’ll be posting more about the new stuff soon in more details. In the meantime, now go download the new version!

 

UNIT TESTING HORROR STORIES – SHARE YOURS NOW!

 

Yeah, we know unit testing is not always easy.

With over 50,000 Typemock users worldwide, we’ve heard it all before: crazy deadlines, pesky bugs and difficult bosses. But we also know that when you stick to it – it’s all worthwhile!

We want to hear your unit testing horror story, whether you succeed or not, [...]

4 Warning Signs that Agile Is Declining

A post by Gil Zilberfeld

I’ve been thinking lately about how agile turned out to be the way we know it today. And the more I think about it, I get more depressed.

You see, agile was supposed to save us all. It was supposed to be the bridge between business and developers.

And 10 years after its [...]

Corporate Innovation with the 80/20 Rule

Don’t forget to register to our free webinar: Introduction to Unit Testing

Tuesday, January 15, 2013 – starts at 10:00 AM EST (3:00 PM GMT)

Register here to join.

 

Does this sound like your company?

This is the fifth comic in a new Typemock comic series. We’ll only make more if you share this one and pass it around [...]