Telerik blogs

Before diving into mocking with JustMock, it’s important to note that JustMock is a mocking framework, and not a testing framework.  Test frameworks allow for creating Test Fixtures, which are .NET classes decorated with the appropriate attributes so they are picked up by a Test Runner.  Test are created within a Test Fixture by writing methods (with the appropriate attributes) that exercise your code (also referred to as the System Under Test) and report the results.  Test Runners are programs that will run your tests.  There are many free testing frameworks available for .NET developers, including MSTest (included with Visual Studio), NUnit, MbUnit, and xUnit.  MSTest is free from Microsoft and uses Visual Studio as the test runner.  The latter three are all free open source software, and come with graphical as well as command line test runners.  One drawback to the free runners is that you have to leave Visual Studio to run your tests, but more on that later.

Since I’ve had several questions about how to get started with these tools, I will show how to setup a test project and execute some initial tests using NUnit, the NUnit Should extensions, and JustMock.

Create a Test Project

Create a new project in Visual Studio.  I usually chose Windows->Class Library, since we don’t need to have any interaction with a user or the console.  Assign the project a name, select Create New Solution (the default) and optionally change the Solution Name.  This is illustrated in Figure 1.

image
Figure 1

In solution explorer, you will see your newly created project with the descriptively named “class1.cs”.  Go ahead and delete this class, as we will be adding new classes that are more meaningful.

Add Required Dependencies

If you haven’t installed the NuGet extension for Visual Studio yet, take a moment to do so now. NuGet allows for quickly adding in required dependencies into your projects as long as they are registered NuGet packages (which all of the tools discussed here are).  More information can be found here.

In solution explorer, right click on the “References” folder to get the following context menu shown in Figure 2.

image
Figure 2

Alternatively, you can select Tools->Library Package Manager–>Add Library Package Reference from the main Visual Studio Menu (see Figure 3).

image
Figure 3

We will start with adding NUnit.Should, which contains a set of extension methods to make NUnit tests cleaner.  One of the great things about NuGet, is that the packages (assuming they are setup correctly) will also bring into your project all of their required assemblies as shown by Figure 4.  So by selecting NUnit.Should, we will get NUnit as well! 

image
Figure 4

Click on install, and it will add reference for both NUnit and NUnit.Should into your project, copy the assemblies to a folder called “packages” off the solution root, and add a file into your project “packages.config”. This file contains information about the packages that were installed via NuGet.

For JustMock, follow the exact same process.  This will download the JustMock Lite into your project, as well as a text file that contains more information on where to find documentation for JustMock.

When complete, if you select Add Library Package Reference again, and select Recent Packages, you will see a window that looks like Figure 5.

image
Figure 5


NOTE: For JustMock, this installs only JustMock Lite, which is the free edition.  For the Complete Edition, please see http://www.telerik.com/products/mocking.aspx to download a fully functional trial version.  For a summary of differences between JustMock Lite and the JustMock Complete Edition, see this page.  If you are adding a reference to the Complete Edition, you would add the reference the “traditional” way – right click the references folder, select Add a reference, and then browse to the install location for JustMock and add the reference to Telerik.JustMock.dll.


Initial Unit Tests

Arrange, Act, Assert

The best way to construct a unit test is using the Arrange, Act, Assert pattern.  The premise for this pattern is to first setup up all of the items that are required for your System Under Test (Arrange), execute the action to be tested (Act), and then assert the results (or non-results) of that action (Assert). 

Creating the First Unit Test

Add a class to the project, and call it “LoginTests.cs”. 

NOTE: By convention in Test Driven Development, classes are named after the objects that they are testing.  In this example, we will be creating a Login class to handle user authentication into an imaginary system.

We have to indicate to the unit testing framework that this class is a test fixture.  In NUnit, we do this with .NET attributes. Make the class “public'” and add the [TestFixture] attribute. You will have to add the using statement NUnit.Framework to the top of your class.


If you are using JustCode, correcting the using statements is very easy.  Activate the JustCode menu by clicking CTL-`, and you will get a dialog as shown in Figure 6.  Select “Add using for ‘NUnit.Framework’” and you are all set.

image
Figure 6


NOTE: In some testing frameworks, this attribute has been made optional.  I recommend still using the attribute for the sake of readability.

The next step is to add a test.  Again, this is done with decorating a method with an attribute, and for NUnit that is the [Test] attribute.  A test is a public void method that doesn’t take parameters (NOTE: there are data driven tests that do take parameters, as shown later in this post).  The test method should be named for what it tests.  There are several schools of thought on this, but I prefer the simple approach of “Should_Do_Something”. For this test, we are testing that the user is validated against the authentication system, so “Should_Validate_User” should do nicely.  My personal preference is to add underscores between the words for readability, but that is also a hotly debated topic.

Finally, you will end up with code as shown in Listing 1:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
 
namespace MyFirstUnitTests
{
    [TestFixture]
    public class LoginTests
    {
        [Test]
        public void Should_Validate_User()
        {
        }
    }
}

Listing 1

We then flush out the body of the unit test. The test that we are going to write is to make sure that the SecurityHandler class actually calls into the UserValidationSevice to verify the user’s credentials. None of these classes are written yet, so we will start from scratch in true TDD (Test Driven Development) fashion.

Our SecurityHandler class will take an instance of IUserValidationService through constructor injection.  To set this up, we need to have an actual instance (funny how .NET requires that).  This is where JustMock comes in.  We need to create a mock of the service, and then set up expectations on the service.  Add the code in Listing 2 to the Should_Validate_User method.

string userName = "Bob";
string password = "Foo";
 
IUserValidationService service =
    Mock.Create<IUserValidationService>();
 
service.Arrange(x => x.ValidateUser(userName, password))
    .Returns(true).Occurs(1);

Listing 2

For more information on JustMock.Arrange, please see my other blog posts on JustMock or refer to the JustMock documentation.

This code will not compile for several reasons.  We don’t have the interface defined, nor do we have all of the correct usings in place.


JustCode makes fixing this code block crazy easy.  First, place the cursor on the IUserValidationService type name.  Activate JustCode (Ctl-`), and select “Create Interface ‘IUserValidationService’” as shown in Figure 7.

image
Figure 7

This will create the interface for you as shown in Listing 3.

public interface IUserValidationService
{
 
}

Listing 3

We still have a few errors in our code.  We need to add using statements for Telerik.JustMock (that corrects the error for Mock.Create) by again pressing CTL-` and selecting “Add using for ‘Telerik. JustMock’”.  We also have to add a using for the Arrange keyword.  In this example, I’ve chose to use the more fluent form of Arrange that is an extension method off the mock variable name.  To use this, we have to add a using for Telerik.JustMock.Helpers.

Lastly, we need to create the ValidateUser method definition on the interface that we created in Listing 3.  To do this, place the editing caret on the ValidateUser method in the lambda expression, and press Ctl-`.  Select “Create Method ‘ValidateUser’ in IUserValidationService’” (see Figure 8) to create the method in our interface definition.

image
Figure 8

By default, JustCode creates the method as a generic (see Listing 4).  This is an offshoot of the fact that the use of the method was in a Lambda expression.  This is easily fixed by changing the method to return a bool and removing the generic.  This gives us the definition that we are looking for (see listing 5).

TResult ValidateUser<TResult>(string userName, string password);

Listing 4

bool ValidateUser(string userName, string password);

Listing 5

The last step is to move the interface to it’s own file, and JustCode makes this trivial.  With the editing caret on the interface name, press Ctl-` and select “Move Type to Another File” as in Figure 9.  This will move the interface to it’s own file, named after the interface name (in this case, “IUserValidationService”.

image
Figure 9


The next step is to create an instance of the System Under Test, in this case the SecurityHandler class. The SecurityHandler class will have a dependency on the service we just created with JustMock, so we inject the service in via Constructor Injection.

SecurityHandler handler = new SecurityHandler(service)

Listing 6


Once again, we have entered a type that doesn’t exist.  Using the same techniques as we did before, we can quickly create the SecurityHandler class with JustCode.  Here we have two different options.  If we have the editing caret on the type name on the left, we get the options listed in Figure 10.  A better option is to place the caret on the type definition on the right (with the service injected).  This gives us the option to create the class and the instructor at the same time (as in Figure 11).

image
Figure 10

image
Figure 11

The second option gives us the class definition in Listing 7.

public class SecurityHandler
{
    private IUserValidationService service;
 
    public SecurityHandler(IUserValidationService service)
    {
        this.service = service;
    }
}

Listing 7

Lastly, we want to move the SecurityHandler into its own file.  Press CRL-` with the caret on the SecurityHandler class name, select “Move Type To Another File”, and it will be moved to a file name “SecurityHandler.cs”.


This completes the “Arrange” part of our Unit Test.  Now, we need to code the “Act”.  We have a single action, “LoginUser”, passing in a username and password as in Listing 8.

bool result = handler.LoginUser(userName, password);

Listing 8

NOTE: It’s very important that you only have one action in each test.  If you have more than one, and the test fails, it can be ambiguous what exactly failed.


We need to create the method LoginUser.  Press Ctl-`, select “Create Method ‘LoginUser’ in ‘SecurityHandler’ (as in Figure 12).  The resulting code is in Listing 9.

image
Figure 12

public bool LoginUser(string userName, string password)
{
    // TODO: Implement this method
 
    throw new NotImplementedException();
}

Listing 9


Our code compiles, but we aren’t yet asserting that our does (or doesn’t do) what we expect.  We gone through a lot of setup (and drove the design of our classes as we needed them to appear), but we haven’t tested anything yet.

NUnit provides a host of assertions that we can use to validate actions (or inactions) in our code.  For this test, we want to verify that the value returned from calling LoginUser is true.  To assert this, we add the line in Listing 10.

Assert.IsTrue(result);

Listing 10

This is using the classic NUnit Assert class.  The NUnit.Should extensions provide for more readable and fluid test code by introducing a set of extension methods that wrap the classic NUnit assertions.  The result is the code snippet in Listing 11.

result.ShouldBeTrue();

Listing 11

With either of these lines in place (you don’t need both since they do the exact same thing), we can now run out test to see if it passes or fails.  To run the test, you can either use the NUnit GUI runner, the NUnit command line runner, or (like I do) use JustCode to execute your tests.


To execute a test using the JustCode Test Runner, place the editing caret anywhere inside your unit test, and then press Ctl-` to activate the JustCode visual aides.  Using the arrows, move over to the “T” (for Testing) and select “Run Tests” as in Figure 13.  As you can also see from the image, pressing the Ctl-Shift-T key cord will execute the test as well without having to go through the visual aides.

image
Figure 13

NOTE: Based on where the editing caret is placed will determine what tests are execute. 

  • Inside a Test: Execute that single test
  • Inside a Test Fixture: all tests in that fixture

The Unit Test Window shows the result of the tests.  If the Unit Test Window doesn’t automatically come up, select JustCode (from the main Visual Studio menu), Windows, Show Unit Test Window…

The Unit Test Window shows all of the tests in the test run and their status. Additionally, you can choose to rerun tests, filter the display, and a host of other functions.  By clicking on a test the details for the test will be displayed in the details pane.

As you can see from this test run (shown in Figure 14), our test failed since we never implemented the LoginUser method of the Security Handler class. 

image
Figure 14


To run this test with NUnit, run nunit.exe (which can be found in the \bin directory where you installed NUnit).  This will bring up the GUI test runner.  Select File->Open Project (or Ctl-O), and navigate to your compiled assembly.  The GUI runner for NUnit (see Figure 15) will allow you to select which tests you want to run as well as show you the results of the test runs.  One major drawback is that the free runners don’t integrate with Visual Studio, so you will have to switch applications to run your tests.  This lack of integration also adds some friction to the process of debugging Unit Tests.

SNAGHTML1654137d
Figure 15

As well as the GUI runner, there is also a command line utility to run your tests.


For this trivial example, the SecurityHandler class will merely pass the call through to the service that we injected into the instance of the handler, so our System Under Test only has one line of code.  The completed implementation of the SecurityHandler is shown in Listing 12. 

public class SecurityHandler
{
    private IUserValidationService service;
 
    public SecurityHandler(IUserValidationService service)
    {
        this.service = service;
    }
 
    public bool LoginUser(string userName, string password)
    {
        return service.ValidateUser(userName, password);
    }
}

Listing 12

Now when we run out test, it passes.  It passes because of the arrangement that we made on the mock through JustMock.  We arranged so the anytime that ValidateUser is called on our mocked service with the specified parameters, it is to return true.  Since we passed through the call to the service from the SecurityHandler using the expected parameters, the mock returned true, the handler returned true, and our test passed.

There is still one last line that we need to add to our test, and that is to take advantage of the extension method “Occurs(n)” that we added to the ValidateUser arrangement.  By adding .Occurs(1), we declared that the method must be called once, and only once.  In order check to make sure that the mock behaved as we expected, you must call “Verify()”.  Listing 13 shows the entire test, with the last line demonstrating the verification of the behavior of the mock.

[Test]
public void Should_Validate_User()
{
    string userName = "Bob";
    string password = "Foo";
    IUserValidationService service =
        Mock.Create<IUserValidationService>();
 
    service.Arrange(x => x.ValidateUser(userName, password))
        .Returns(true).Occurs(1);
 
    SecurityHandler handler = new SecurityHandler(service);
    bool result = handler.LoginUser(userName, password);
 
    //Next line is commented out since we are 
 
    //using the Should extensions
 
    //Assert.IsTrue(result);
 
    result.ShouldBeTrue();
 
    service.Assert();
}

Listing 13

The last line asserts that the Mock behaved as we expected it to.

There is a lot more capabilities built into JustMock, NUnit, and NUnitShould.  Hopefully this got you started down the path of Unit Testing TDD style.  Be sure to stay tuned to this blog for a lot more information on unit testing as mocking.

Happy coding!

JustMock blog banner


Japikse
About the Author

Phil Japikse

is an international speaker, a Microsoft MVP, ASPInsider, INETA Community Champion, MCSD, CSM/ CSP, and a passionate member of the developer community. Phil has been working with .Net since the first betas, developing software for over 20 years, and heavily involved in the agile community since 2005. Phil also hosts the Hallway Conversations podcast (www.hallwayconversations.com) and serves as the Lead Director for the Cincinnati .Net User’s Group (http://www.cinnug.org). You can follow Phil on twitter via www.twitter.com/skimedic, or read his personal blog at www.skimedic.com/blog.

 

Related Posts

Comments

Comments are disabled in preview mode.