Lesson #1 - Common Test Driven JS Problems

There are a lot of common problems I have run into when writing JavaScript unit tests. Here are a few of them I want to address before getting to the meat of the lessons.

Multi-Responsibility

The biggest problem I have run into when trying to test JavaScript is how even simple functions are doing way too much. Take for instance the sample code below. It takes data from a form, does a little bit of validation and then pushes it up to a REST service. It is not a very complex form, it has some minor validation before a POST request would be pushed up to a REST service. From a functionality standpoint, there is nothing wrong with the JavaScript code. This is probably something you have written hundreds of times. If you wanted to you, could write this in your sleep. However, the code is doing a lot more than meets the eye. It is selecting data from the DOM, validating that data, and then selecting that same data again to push up to the REST service. The tests would have to fake out the DOM as well as a REST service. The more you have to setup in your tests, the more brittle they become and the harder they are to maintain. Your tests shouldn't have to setup all the HTML needed so the selectors will work. Nor should the tests require a REST service to be up and running. The test should just make sure the validation is working and if all the validation passes an AJAX call is made.

Bad Code Structure

Let's assume for a second this form was on its own page. In addition to the form, maybe the page also allows the user to login. The login form also requires some validation prior to logging in. Initially the application isn't too big, so all the JavaScript is stored in a single file, site.js. As the application organically grows more and more functionality is added to site.js. DOM manipulation, JQuery selectors, business rules, AJAX calls. Some of the practices I have seen is to break the JavaScript out by page, login.js, pictures.js, and so on. But that hasn't really helped anything, the structure is still bad. Now it is just bad in multiple places. It is almost impossible to unit test all that spaghetti code. You run into the same issues as before, HTML and a REST service needs to be setup just to test some business logic.

Too Much Logic in UX

Putting too many business rules into your UX layer is just asking for trouble. Hiding and show fields/columns and what not makes sense to have in the UX layer. But it shouldn't have complex business rules which require a lot of unit tests. Chances are you going to have to repeat those rules somewhere in your logic layer which leaves with two problems, duplicate logic, and duplicate tests. Which makes your life a lot harder than it needs to be. I would look for ways to push the business rules into a centralized place for both the logic layer and the UX layer to interact with.