Bugfree.dk – Ronnie Holm's blog

Not anti-anything, just pro-quality

An example of unit testing using TypeMock

Posted by Ronnie Holm on February 11th, 2009

This post details my first use of TypeMock, a commercial mocking framework, for testing a web part that displays a dropdown bound to a LINQ query. Based on the item selected, the web part then displays a result bound to another LINQ query. For the purpose of becoming familiar with TypeMock, though, the focus of this post is on testing the code that initializes the LINQ data context. It does so by reading a connection string from a configuration file and passing it to the data context.

In order to test code whose branching behavior depends on a value read from a configuration file, the test should provide various inputs and assert that the code under test acts accordingly. In addition, the test should run in milliseconds to encourage frequent runs and it should be self-contained, meaning no setup should be required before running the test. These requirements are best met with the web part running in a controlled environment. Yet, as far as the code under test goes, it should behave as if part of an Asp.Net page.

For the sake of brevity, here’s my web part with the code to initialize the data context:

    public class MyWebPart : WebPart {
        MyDataContext _db;    /* LINQ database context */
        string _error;        /* Early stage error message */    	

        public MyWebPart() {
            Initialize();
        }

        private void Initialize() {
            string c = GetMyConnectionString();
            if (c == null)
                 _error = "Unable to do something";
            else
                _db = new MyDataContext(c);
        }

        private string GetMyConnectionString() {
            System.Configuration.ConnectionStringSettings c =
                System.Configuration.ConfigurationManager.
                    ConnectionStrings["MyConnection"];
            return c == null ? null : c.ConnectionString;
        }

        protected override void Render(HtmlTextWriter w) {
            // display error message if set
        }
    }

Notice how the constructor calls out to an Initialize method. Otherwise code within the constructor would fire before I’d have a chance to setup a controlled environment around the web part and I wouldn’t be able to test it. Turning the attention to Initialize itself, it’s made up of only a simple if statement. The idea is that if I can’t mock something as simple as reading a value from a configuration file, most likely I can’t mock something more involved either. On the other hand, for a developer already familiar with TypeMock and test first development, the code above may be born of the need to satisfy a failing test.

I want to test Initialize by controlling how GetMyConnectionString gets to return the connection string. While running in an Asp.Net context, GetMyConnectionString would attempt to read the string from web.config. Within my controlled environment, however, I want to inject into the web part an alternate implementation that returns a value of my choosing. That way I can control the path through Initialize and inspecting the state of the _error or _db fields, I’m able to determine if the code behaved as intended.

Using the method chaining DSL of TypeMock, the test takes on this form (of course, having more tests, I’d move shared code into helper methods decreasing the test to code ratio):

    [TestClass, ClearMocks]
    public class MyWebPartTest {
        [TestMethod, Isolated, VerifyMocks]
        public void Should_set_error_message_when_no_
                    connection_string_is_configured() {
            // arrange
            MyWebPart fake = Isolate.Fake.Instance<MyWebPart>();
            Isolate.NonPublic.WhenCalled(fake,
                "Initialize").CallOriginal();
            Isolate.NonPublic.WhenCalled(fake,
                "GetMyConnectionString").WillReturn(null);
            PrivateObject handle = new PrivateObject(fake);

            // act
            handle.Invoke("Initialize", null); 

            // assert
            Isolate.Verify.NonPublic.WasCalled(fake,
                "GetMyConnectionString");
            string error = (string)handle.GetField("_error");
            MyDataContext ctx = (MyDataContext)handle.GetField("_db");
            Assert.AreEqual("Unable to do something", error);
            Assert.AreEqual(null, ctx);
        }
    }

There’re three parts to tests using TypeMock: (1) the arrange part sets up expectations of what’s going to happen when a method, a property, or some other part of the code under test is invoked; (2) the act part carries out the actual interaction with the object under test, turning to PrivateObject to invoke the Initialize method; and finally (3) the assert part verifies that what was supposed to happen did happen. Worth noting is that this test asserts both state and behavior, i.e., as part of executing the code under test, _error or _db should’ve been set to an appropriate state and GetMyConnectionString should’ve been called once and only once.

This concludes my example, which I believe illustrates the basics of testing and mocking using MS Test and TypeMock. Comparing and contrasting TypeMock to other popular mocking frameworks, TypeMock has the distinct feature that it can mock almost anything, with or without using interfaces. Some argue that not enforcing the use of interfaces is also the disadvantage of TypeMock, because for code to be truly testable, it should be modularized using the Inversion of Control principle. However, with legacy code, such as the .Net framework or the SharePoint API, to me TypeMock appears to bridge the two worlds nicely, leaving the developer in charge.

To learn more about the basic concepts of mocking, Inversion of Control, and Dependency Injection (containers), I’d recommend listening to a couple of Alt.Net podcasts: Dependency Injection and Inversion of Control and More Dependency Injection and Inversion of Control.

  • Share/Bookmark

2 Responses to “An example of unit testing using TypeMock”

  1. Bugfree.dk » Blog Archive » My unit testing guidelines Says:

    [...] far as tooling goes, MSTest or NUnit should be used in concert with TypeMock or Rhino Mocks. The use of TypeMock may be preferred over Rhino Mocks because of its approach to [...]

  2. Bugfree.dk – Ronnie Holm's blog » Blog Archive » Unit testing LINQ to SQL using TypeMock Says:

    [...] loading a mock implementation at runtime, the new breed of mocking frameworks hooks into the CLR to intercept and redirect calls. This opens up virtually every aspect of a class to mocking, which is useful for testing code not [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>