Unit test principles

Jan 11 2018

WHY even write unit test?

The most obvious answer is to check that the code we write works the way we intended. Now this is true and a good reason to write unit tests but i think the best thing you earn from writing unit tests is preventing your code from breaking. If someone break your code he’ll know about it once the amazing unit tests you wrote fail.

HOW to write unit tests?

Basically you want to keep your tests simple and readable (like your code! KISS), so that when someone breaks your test he doesn’t need to start figuring out what the test is suppose to do or how it’s implemented (and he doesn’t want to smash your computer). The main principles for writing unit test:

TLDR -

1. Test ONE behavior in each test.
2. Create the minimal setup you need for each test.
3. Use before and after blocks to make your test cleaner.
4. Split a function that is hard to test into smaller functions that are easier to test.

** the code is written in JS with Jasmine syntax (testing framework for angular)

  • Test only one behavior in each test -
    When you test only one behavior you will have an easier time debugging once the test failed. Another plus is that when you add a certain behavior to a function you won't need to start changing all your tests, just add a test to test the behavior you added.

    Instead of this:

    describe('greetUserAndUpdateStatus()', () => {
    it('should create user and set status as active', () => {
    const result = greetUserAndCheckStatus('[email protected]');
    expect(result).toEqual('Hello Dennis!');
    expect(users.status).toEqual('active');
    });
    });
    

    do this:

    describe('testing one behaviors in the each test', () => {
    it('should return Hello user', () => {
    const result = greetUserAndCheckStatus('[email protected]');
    expect(result).toEqual('Hello Dennis!');
    });
    it('should set user status to true', () => {
    greetUserAndCheckStatus('[email protected]');
    expect(users.status).toEqual('active');
    });
    })
    
  • Minimal test set up -
    Do the setup you need ONLY for the specific behavior you are testing. This will help you keep your test simple and maintainable.
    Instead of this:

    describe('createNewUser()', () => {
    it('should create user', () => {
    const users = [];
    const newUser = [{
    first_name: 'dennis',
    last_name: 'bergkam',
    email: '[email protected]',
    country: 'Netherlands',
    }];
    createNewUser(user);
    expect(users[0]).toEqual(newUser);
    });
    });
    

    if all you need to create a new user is an email then do this:

    describe('createNewUser()', () => {
    it('should create user', () => {
    const users = [];
    const newUser = [{email: 'dennis_b[email protected]'}];
    createNewUser(user);
    expect(users[0]).toEqual(newUser);
    });
    });
    
  • Use also beforeEach (or afterEach) blocks to simplify and keep thing small and tidy:
    Instead of:

    describe('making the same setup in a couple of tests', () => {
    it('should return some string', () => {
    controller.someFlag = false; 
    const result = controllerFunction();
    expect(result).toEqual('some string');
    });
    it('should set controller flag to true', () => {
    controller.someFlag = false; 
    controllerFunction();
    expect(controller.someFlag).toBe(true);
    });
    })
    

    Do this:

    describe('using beforeEach blocks', () => {
    let result;
    beforeEach(() => {
    controller.someFlag = false;
    result = controllerFunction();
    });
    
    it('should return some string', () => {
    expect(result).toEqual('some string');
    });
    it('should set controller flag to true', () => {
    expect(controller.someFlag).toBe(true);
    });
    })
    
  • If you need too much setup or have a hard time writing a unit test then your function is probably to complex and should be split into smaller functions.

Regardless of what language you use and which framework you should follow these principles. I guarantee that writing unit test will make you a better developer and help you maintain your code plus no git blame for you!

some links that will help you get started with unit testing -
Udacity javascript testing free course
Angular testing documentation
Angularjs unit testing documentation

Bar B.
Software Developer
Back to Blog