Sunday, 30 January 2011

A Guide to Test Driven Development in Flex – Part 2: Writing The Unit Tests

In part 1 of this series we defined the public properties on the class we’re testing (referred to as the System Under Test or SUT) and wrote some empty unit tests. You can see the code here. When we run these empty unit tests un-surprisingly they all fail:

And they all give the same failure trace:

It is now time to start implementing these test methods but before we do that we need to do a bit of setup. For example rather than creating a new model to test in each test we can just have a private variable that will always be available for all the tests:

(I use an underscore to signify a private variable)

Now that we have an instance of the model to test we can start defining what each test will check for. The first test – testAutoCompletePM simply tests that the model is in the state that we expect after construction. All we need to do for this test is assert that the showAutoCompletePopup property is false:

The string in quotes is just the message that will displayed in the error. It lets us know what property we are expecting to be false.

The next test popupOpensOnStartSymbol is a bit more involved. We want to check that when the user types the start symbol that the showAutoCompletePopup is set to true and that the binding fires. We’ll probably want to use the same starting symbol in all these tests. So that we don’t have to set it each time we can do this in a setup function:

The static constant means that we are not using magic strings in our tests. We can use the same static when we test the functionality of the class as we do here in the second test – popupOpensOnStartSymbol:

This test is nearly complete but we need to test that the binding event is dispatched as well. As this is a read only property we will use a named bindable and dispatch a custom event type. Event types should always be constants so that we don’t use magic strings. We can define this constant in the SUT but as it is just for binding we don’t want to make it public. Nothing will ever add an event listener for this type. If it is private though the test will not be able to assert that the event is dispatched. Because of this I use the internal namespace for these binding event constants. This means that most classes can’t see it but that tests that are in the same package will be able to see it:

We can then update our test to make sure that this event is dispatched when the popup is supposed to open:

In the next test – popupRemainsClosedNonStartSymbol we need to make sure that showAutoCompletePopup remains false and that the binding event is not dispatched:

We follow a similar process for the other tests as well. I also added a couple of extra tests for testing selecting an item to test for different labelField values.I also had to create a CloseAutoCompletePopupEvent that we expect to fired when we finish editing. Once finished you’ll end up with something like this.

When we run these tests we get the following:

We can see that most of the tests fail. Only 2 pass, the test verifying the initial start-up state of the class and the test that verifies that nothing happens when we type anything other than the startSymbol.