Using StructureMap Inject To Avoid External Dependencies In Integration Tests

Posted almost 2 years ago on July 16, 2011

At the end of last week I wrote a class to manage sending e-mail from our application. This class (called it EmailProcessingManager) had all the usual suspects:

  • Get a list of to, cc, bcc, from and reply to email addresses
  • Find a template
  • Replace tokens in said template with values from the database
  • Send the email(s)

Wound up making a class for each one of these separate duties and wrote tests for each. But to seal it all together, I wanted to write an integration test that would test the whole operation of sending an email. This test would hit the database, pull in the actual HTML template, replace token values, etc. But what about the actual sending of email? I didn't want to go to the trouble of trying to figure out how to hit a pop email inbox and reading in the email...there had to be an easier way!

ObjectFactory.Inject() to the rescue!

The problem I had was that I wanted to use the entire EmailProcessingManager class as it would be used in production, except I didn't want the mail to actually go out. I wanted all the classes' dependencies to be real implementations except for the class that actually spun up the SMTP client class to send the mail. That's when I found the Inject method.

(Using Moq in this example)

<TestFixtureSetUp()>
Public Sub Setup()
    _mailSenderMock = New Mock(Of IEmailSender)
    _mailSenderMock.Setup(Function(mock) mock.SendEmail(It.IsAny(Of List(Of MailMessage)))) _
        .Callback(Sub(messages) _emailsThatWouldHaveBeenSent = messages)
        
    'Inject the mocked object instead of using the production code
    StructureMap.ObjectFactory.Inject(Of IEmailSender)(_mailSenderMock.Object)

    'Get an instance of the class under test
    _emailProcessingManager = StructureMap.ObjectFactory.GetInstance(Of IEmailProcessingManager)()        
    
    Dim recipientList = New List(Of String) From {"paco@joescrabshack.com"}
    _emailProcessingManager.ProcessEmailRequest(EmailType.Registration, recipientList)   
End Sub

<Test()>
Public Sub Can_create_a_request_for_an_authorization_email_and_have_it_sent_to_the_recipient()
    _emailsThatWouldHaveBeenSent.First(Function(email) email.To.First().Address = "paco@joescrabshack.com").ShouldNotBeNull()
End Sub  

All of the value of an integration test, but none of the pain of dealing with an external dependency. I like it.

Now that I've discovered this, I have other ideas for it's use. One situation that comes to mind is an integration test that saves a complex object graph to the database. Those tests are always hard to clean up after, so instead of saving the object I'll just use a mock to retrieve the passed object and do my asserts. No messy cleanup!

Creating a Stub That Redirects Input Parameter to Method Return Value

Posted about 2 years ago on June 01, 2011

In the case where you want to create a stub that simply passes the input parameter through to it's return value, you can use this syntax in Moq:

mock.Setup(m => m.Method(DateTime.Now)).Returns((DateTime param) => param);

Documenting this here because I use it just often enough to forget.

Javascript Testing With JasmineBDD: Overriding Spy Return In Nested Describe

Posted about 2 years ago on April 30, 2011

I have been using Jasmine’s SpyOn method to stub results for dependencies within methods.

My goal was to override these stubbed methods in nested describe contexts. My first thought was to redefine the Spy (stub) using the spyOn method. This fails with an obvious error message: “Error: xyz has already been spied upon…”. What I needed to understand was that the spy object had already been created in the outer describe block, so I needed to simply re-use it. Instead of trying to re-declare the spy, just use the same object and use the andReturn() method to redefine the return value of the stubbed method.

Here is an illustration:

describe("Outer describe", function() {
    beforeEach(function() {
        //Setup Stuff
        spyOn(someObject, 'someMethod').andReturn(3);
    });

    it("...", function() {
        //Test here
    });

    describe("Inner Describe", function() {
        beforeEach(function() {
            //Nested setup stuff

            //Fails: "Error: someMethod has already been spied upon"
            spyOn(someObject, 'someMethod').andReturn(0);

            //Passes: The object has already been initialized as a spy, so use the existing spy object and tell it to change the return value.
            someObject.someMethod.andReturn(0);
        });

        it("...", function() {
            objectUnderTest.someMethod();
            expect($("input#some-element")).toBeDisabled();
        });
    });
});

Javascript Testing – Getting in the Groove

Posted over 2 years ago on October 23, 2010

The past week has been spent continuing my journey of refactoring massive amounts of javscript that was written baked into the jQuery ready callback

Nagging Questions

While I've been pulling out behavior and encapsulating it into javascript objects, a few design questions keep popping up.  First, when I need to interact with the DOM I struggle with how to make my object aware of the page elements.  I have at least a few options:

* Inject the DOM elements into the object constructor:

function SomeClass(element1, element2) {
  this.element1 = element1;
  this.element2 = element2;
}

This solution allows me to not have to worry about adding DOM elements to a test fixture.  In my test I can just pass object literals into the ctor.  The tradeoff is that if the object depends on many elements then the constructor parameter list can get unwieldy. 

* Allow the object constructor to locate the elements:

function SomeClass() {
  this.element1 = $("input#Element1");
  this.element2 = $("input#Element2");
}

Here I can avoid the big ctor parameter list, but now I have to simulate some of my DOM elements inside the test.  The testing framework I'm using makes this very easy, but there's something troubling about duplicating the elements here.

* Pass page elements into object instance methods as needed

function SomeClass() {
  this.user_took_some_action = function(element1, element2) {
    //Do stuff
  }
}

This might appear be a happy medium between the other two solutions, but it also breaks some of the encapsulation I'm trying to achieve.  There are often times where two or more instance methods interact with the same DOM elements. 

I?ve been trying to observe my TDD patterns to see what leads me to the most testable solution, but it seems like every situation is different.  I'm torn on whether or not I care about consistency.

The next question I keep bumping into is dealing with service location.  Do I pass the dependencies into the constructor and/or instance methods, or just create them inside the instance methods?  Coupled with the above discussion, my parameter lists can start to get muddled with both DOM elements AND dependencies.  Not ideal.  Ideally I would just create dependencies as I need them inside my instance methods:

function SomeClass() {
  this.user_took_some_action = function(element1, element2) {
    var dependency = new Dependency();
    dependency.make_me_some_pie();
    //other stuff
  }
}

Since javascript is a dynamic language I thought it would be a breeze to stub out the dependency, and it is...but only after I asked the Twitters for some help:  http://gist.github.com/639861

This seems like a great way to go if you don't mind the extra work/code of stubbing using this technique.

Javascript Testing – Starting Out

Posted over 2 years ago on October 16, 2010

It's been a while since I realized that I had a need to test my Javascript code.  The team I'm working with during the day is building a rich internet application using Javascript and JSON web services.  Sales running through our application are in the 10s of thousands each day.  If our application displays something incorrectly, or doesn't respond to a user interaction in the correct way we are on the line for the cost to our clients.

Like I said, it's been a while since recognizing the need, so what took so long?  For some reason testing Javascript has been a really difficult thing for me to grok.  I sat down at my computer determined to learn probably 4 or 5 times before finally feeling like I had a handle on what I needed to do.  So what was the hangup?  2 big things:

1) Hadn't unlocked the secrets of Javascript's OOP abilities.
2) My Javascript was married to the DOM.

The biggest mind shift that I had to make was thinking like I think when I'm writing in C# or VB: use OOP to my advantage!  This isn't as obvious as it looks partly because Javascript's object syntax is... different.  To understand objects, public methods, private methods, and properties I found this article to be a huge help.  This shift in thinking was critical to becoming successful at testing Javascript.

Next up is isolating user interaction behavior from the DOM.  I'm new at this, but so far what has served me well is to group page elements into logical pieces, and encapsulate their behavior.  For instance, in our application we have a "toolbar" that responds to interactions that the user makes on other elements on the page:

Capture

Before refactoring to objects, we were writing all of our user interaction behavior in the $().ready(...) function from JQuery.  Organizing logic like this simply does not scale.  You end up losing sight of interactions on elements and it becomes too easy to miss something.  To solve that problem we encapsulated the toolbar in an object: 

function SelectionToolbar(saveButton, getCountsButton, saveDefaultsButton,
    radiusButton, featheringButton, mapButton, ...) {
    this.saveButton = saveButton;
    this.getCountsButton = getCountsButton;

...and so on.

It's called from the page like this:

var selectionToolbar = new SelectionToolbar($("input#SaveQuery"), $("input#GetCounts"), ...etc

A nice side effect is that I don't have to keep referencing the DOM element name ever again.  When I change the ID of the DOM elements I only have to change it one place in my Javascript.

When events happen on the page that have an effect on the toolbar, we simply notify the object of the interaction, and the behavior gets applied to the toolbar elements internally.  This is the encapsulation we've been needing!

In this post I've described how I changed my mindset to get the code in position to be unit tested.  Next up I'll walk through the first test I wrote and more about the framework I chose to support testing.

If you have any beginner tips to share about getting started with Javascript OOP or testing please leave them in the comments!