Mocking: Part 1 – Mocking Concepts

Posted April 26th, 2011 by JeffBNimble with 3 Comments

Background

I began writing unit tests to verify the correctness of my code nearly 15 years ago. At that point in my career, I was earning my living writing Smalltalk. That was a time when developers used to actually subscribe to magazines and these magazines were delivered monthly right to your door via the U.S. Postal Service. For a mere $129 per year, I got 12 monthly issues of The Smalltalk Report. In October of 1994, Kent Beck wrote an article published in The Smalltalk Report entitled Simple Smalltalk Testing. After reading that article a couple of years later, I downloaded a testing framework he wrote called SUnit and have since written too many unit tests to count.

Until recently, my unit tests were cobbled together with all of the various classes in the application. Though I’d been writing unit tests for nearly 15 years and arguably they were effective, they were complicated, brittle, difficult to maintain and even more difficult to comprehend. I violated practically every best practice relating to writing effective unit tests (but I’ll save this for another blog article).

About three years ago, I was first exposed to the concept of mocks as they relate to unit testing. This was a completely foreign concept to me and I must admit that I initially did not understand them or why they were necessary. After all, I have all of the classes in my application available to me, why on Earth would I ever need mocks?

Over the course of the past year, I really began focusing on honing my unit testing skills and I’ve come to love mocks and what they do for me. The quality and effectiveness of my unit tests have improved 1,000% and my use of mocks has made a world of difference for me. In talking with many of my colleagues and others I’ve met at conferences or on Twitter, it’s clear to me that many developers are confused and bewildered about mocking as I was. So, I decided to write about it and share with all of you in hopes that I might help clear things up a bit.

This is my first lengthy blog post and it will hopefully be the first of a handful of writings on the topic of unit testing and mocking.

Introduction

Part 1 of this series on mocking and testing will focus on the concepts. Since this is primarily conceptual, I’ll not deep dive into code or frameworks until Part 2.

In this article, I will answer the following questions:

  1. What is mocking?
  2. Why mock?
  3. What are the key mocking concepts?
  4. What are the benefits of mocking?

What is mocking?

Outside of the world of software development, the term “mock” means to imitate or to mimic. A “mock” can therefore be thought of as a stand-in, an imposter or as most commonly referred to as it pertains to software development, a fake.

Fakes are often used as stand-ins for dependencies of the class under test.

Terms & Definitions

  • Dependency – A dependency is when one class in an application depends upon another in order to perform its intended function. Dependencies are often stored in instance variables inside of the dependent class.
  • Class Under Test – When writing unit tests, the term “unit” generally refers to a single class and specifically the class against which the tests are written. The class under test is therefore the application class that is being tested.

Throughout the remainder of this post, I will use a realistic, but simple example for illustration purposes. The classes in my example are not unlike classes that may exist in your application.

LoginCommand class

LoginCommand is a very simple class that executes a login service. It so happens that the login service is a separate class and therefore a dependency of this class. Notice that the login service is expressed as an interface and that there is some mildly interesting validation logic.


ILoginService interface

ILoginService is a dependency of the LoginCommand and is a simple interface declaring only two functions; login and logout.


LoginCredentialsVO

LoginCredentialsVO is a simple model class that wraps two pieces of data required to login; the username and password. The “VO” suffix identifies this class as a special type of model known as a Value Object.


Terms & Definitions

  • Value Object – A value object is a special type of Model class that serves as a wrapper around multiple individual pieces of data. A Value Object is often used to group similar data together into a class. Value Objects typically don’t contain any functions or logic.

Given this small collection of application classes, I would likely choose to unit test the LoginCommand as it contains both logical code and some interesting behavior that I would like to verify. Consequently, the LoginCommand would become my Class Under Test.

Why Mock?

When you write unit tests, you are exclusively concerned with verifying the behavior of the Class Under Test for all reasonable scenarios. Conversely, you are not concerned with the behavior exhibited by any of the dependencies when the Class Under Test interacts with them during the execution of tests.

For example, invoking the LoginCommand.execute() function potentially invokes the ILoginService.login() function. However, we are not concerned with what happens when the service is invoked.

When we execute our tests against the LoginCommand, the only thing we can really test is various scenarios that invoke the LoginCommand.execute() function. After all, it is the only public function. Here is a list of scenarios we might like to test:

  1. Verify that the LoginCommand invokes the ILoginService.login function passing the username and password when both are specified
  2. Verify that an error is thrown when the UserCredentialsVO contains a null username
  3. Verify that an error is thrown when the UserCredentialsVO contains a null password
  4. Verify that an error is thrown when the UserCredentialsVO contains a blank username
  5. Verify that an error is thrown when the UserCredentialsVO contains a blank password

When we execute our tests, we must make sure that the LoginCommand has a reference to an ILoginService implementation. If that dependency is not provided to the LoginCommand, a Null Pointer Exception will result and all of our tests will end in error.

Our application will certainly contain an implementation of the ILoginService that invokes a remote service using mx:RemoteObject, mx:HTTPService or mx:WebService. If our application already contains such a class, why not just use that in our tests? After all, we need to test that, right?

Take a moment and think about what happens to the level of complexity in our unit tests if we use the real implementation of ILoginService that communicates with a remote service somewhere on our local machine or on the network. Suddenly, in order to run our unit tests, we have to have a running service somewhere. We also have to make sure that the machine running the tests is connected to the network. We must also ensure that the username and password are valid and that the invocation of the real service will not fail. What if the server-side code has not even been written yet? Pulling in this real implementation causes us to have to worry about all sorts of things that could cause our tests to fail. While testing with the real service might be a desirable goal, it is not a goal of a unit test.

Instead, wouldn’t it be cool if we could plugin a fake service that didn’t really do anything? Wouldn’t that be much simpler? If we do that, we no longer have to worry about networks and servers and real usernames and passwords. Using a fake greatly simplifies our unit testing.

So, how do we provide the fake to the LoginCommand? There are a number of ways you can probably think of. We could create our own fake implementation of the ILoginService class. That’s simple enough. There are only two functions we would need to implement. If we didn’t happen to express the service as an interface, we might instead choose to subclass the real service class and create a fake subclass by overriding the public functions.

Both of those alternatives involve a similar amount of effort and result in extra code to write and extra classes to create and maintain. Wouldn’t it be great if something could just generate the fake for us and we don’t have to worry about creating new classes and maintaining them? There are mocking frameworks that do just that. But, I’ll save the specifics of that for Part 2.

There are a handful of other issues that may result from using real application classes as our dependencies. When we write a unit test, it is essentially a class not unlike any other class. The class has code that creates an instance of the class under test, invokes a function on it and observes and verifies what happens.

If we use a real service, how is our test supposed to verify whether the LoginCommand invoked the ILoginService.login function? It is simply standing off to the side observing what happened. From a testing perspective, we only want to verify that the LoginCommand invoked the ILoginService.login function with specific arguments.

So, let’s summarize why we mock. First and foremost, we use fakes to simplify our tests. Secondly, there are certain types of verifications that are difficult or outright impossible without using fakes.

You might be wondering at this point, why there was no discussion of making a fake UserCredentialsVO. While you certainly could do that, what benefit would there be? This application class is sufficiently simple and its use in unit testing scenarios does not introduce additional complexity.

What are the key mocking concepts?

When it comes to mocking, there are only 3 things you really need to worry about; stubbing, setting expectations and verifying.

Some unit test scenarios don’t involve any of these, others involve only stubbing and others involve setting expectations and verifying.

Stubbing

Stubbing is the process of telling your fake how to behave when it is interacted with. You can generally stub public properties (those with getters and/or setters) and public functions.

When it comes to stubbing functions, you have a lot of choices typically. You may wish to return a specific value, throw an error or dispatch an event. Further, you may wish to indicate that the function behave differently depending upon how it is invoked (i.e. by matching the types or values of the parameters passed to the function).

If this sounds like a lot of work, it can be, but it generally isn’t. One great feature of many of the mocking frameworks is that you need not stub void functions. Nor do you have to stub any functions that are not invoked or properties that are not consulted during the execution of your tests.

Setting expectations

One of the key features of a fake is the ability to tell the fake what you expect when your test runs. For example, you may expect that a specific function be invoked exactly 3 times. You may expect that it never be invoked. You may expect that it be invoked at least twice, but not more than 5 times. You may expect that it be invoked with specific types of arguments or specific values or any combination of the above. The possibilities are endless.

Setting expectations is the process of telling your fake what you expect to happen to it. Remember that since it’s a fake, nothing actually happens. But, your class under test is none the wiser. From its perspective, it invoked the function and expects that it did whatever it was supposed to do.

For what it’s worth, most mocking frameworks let you create mocks of interfaces or public classes. You are not limited to having to mock only interfaces.

Verifying

Setting expectations and verification go hand in hand. Setting expectations is done prior to invoking the function(s) on the class under test. Verification is done after. So, first you set expectations, then you verify that your expectations were met.

From a unit testing perspective, if your expectations were not met, the unit test fails. For example, if you set the expectation that the ILoginService.login function should be invoked exactly once with a specific username and password, but it was never invoked during the execution of your test, then the fake would not verify and the test should fail.

What are the benefits of mocking?

There are many benefits that are to be had by using mocking instead of real application classes. These benefits include:

  1. Significant reduction in unit test complexity
  2. Significant reduction in the number of external dependencies (i.e. networks, servers, databases, etc.)
  3. Less code to write
  4. Tests can be written more quickly
  5. Tests run much more quickly

Summary

My goal in writing this blog entry is to introduce you to the concept of mocking in regards to unit testing. In Part 2, I will show some code samples and show you how concise and simple unit tests are when using a mocking framework. I will also introduce you to my favorite mocking framework for AS3, but include references to others that I’m aware of.

I hope that you found this article helpful and I welcome your feedback, questions, comments and input.

360|Flex session survey results

Posted April 21st, 2011 by JeffBNimble with 1 Comment

So like this one time….at band camp….I spoke at 360|Flex in Denver. My session was entitled IoC Concepts with examples in Swiz, RobotLegs and Parsley.

I want to thank everyone that attended and especially those that provided feedback. Feedback is extremely helpful for those that speak or present. It lets us know how we’re doing and what we need to change to improve. The most beneficial type of feedback to me is when someone takes the time to provide constructive commentary.

So, for those of you that missed it, I’ll provide a link to the recorded session once it has been published.


IoC Concepts with Examples in Swiz, RobotLegs and Parsley

Inversion of Control (IOC) is all the rage of late and all of the latest generation of Flex frameworks are IoC implementations including Robot Legs, Swiz and Parsley. A thorough understanding of the underlying concepts will help you to not only choose the best framework for your use, but also to utilize those frameworks most effectively. This session will cover the important concepts including dependency, coupling, injection and the benefits that are had by using an IoC framework. Some coverage of the current popular frameworks will be given to see how each implements IoC. We will examine some of the drawbacks/issues of using IoC with Flex and also discuss some practical approaches to using IoC on your projects.


Respondants: 9 What the user Expected? 100.00 % Slides Useful: 100.00 %
Average Rating: 4.44 out of 5 Session Informative? 100.00 %    

Was the speaker authoritive?

  • Jeff gave lots of information about IoC and the specific frameworks in his talk. Also enjoyed hearing about his background in programming.

Was the Session Informative?

  • It was good to learn about the concept of IoC in general and learn more about the presented frameworks. There was a good amount of theoretical as well as practical information.

Were the Slides Useful?

  • Always like code in the slides

Additional Comments:

  • Send your slides to Joel first next time.
  • Really enjoyed Jeff’s talk. He was an engaging and knowledgeable presenter and I would love to see another of his talks.

360|Flex slides and sample code

Posted April 14th, 2011 by JeffBNimble with 2 Comments

My 360|Flex slides and sample code are online and available. These are from my IoC Concepts presentation at the 2011 360|Flex conference in Denver.

Please feel free to give me a shout or leave comments or questions.

Twitter