Damian Nicholson: Writing (testable | maintainable | scalable | rock solid) JavaScript
Damian Nicholson (@damian) was talking about writing good JavaScript code at Scotland.js, these are my notes from his talk.
We all want to write good, maintainable code.
How can this be achieved?
JavaScript + Unit testing = Good code
By unit testing our code it becomes better. Makes sure we don't create regression bugs. Good code is a byproduct of unit testing - simply by writing unit tests your code will get better.
When adding information to a page, typically we would bind to the submit handler and then add a callback to an Ajax success handler. This is untestable as we have anonymous functions, tight coupling, nested callbacks and HTML templating. If code is hard to test its a good sign that you need to refactor your code.
Testing forces you to encapsulate all your code into objects which means we can test each method. Frameworks like Ember and Backbone are good examples of this. Single Responsibility Principle is easier with objects. Also promotes decoupled and intuitive code. Writing tests first makes sure your code is testable.
Internal state via properties, named functions, single responsibility principle, loose coupling. To test we assert against properties and things being called.
How much time should I spend testing?
Test as little time as possible testing to gain a level of confidence.
What should you be testing?
Your public API. The internals don't matter as long as the end result is correct.
How do I test my jQuery
This is difficult but test jQuery's API. Stub out jQuery's functionality to check that it is being correctly called.
Summary
- Unit tests are a win
- JS objects are a win
- Only test your public API
What next?
- data-attributes - use these instead of classes and id.
- Lifecycle hooks - trigger events throughout the UI interaction to allow subscription.
- Wrap interface to plugins - means you can easily swap out plugins.
- Leverage mixins - use
$.extend()
to add common methods. - Keep HTML out of JS - use a templating language.
- Leverage private functionality - only expose what you need to.