Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Test-driven Client-side JS

Pete Hodgson
February 04, 2015

Test-driven Client-side JS

Presented at ForwardJS, Feb 2015
VIDEO: https://forwardjs.com/lectures/33

Writing high quality, maintainable client-side code is becoming increasingly important as we continue to move more logic into the browser. This talk will show how unit-testing and test-driven development helps you build better quality code, faster.

We'll see examples of building a React app test-first, then look at techniques and tools to solve the trickier parts of unit-testing in JavaScript. You'll see how TDD guides us towards cleaner and more maintainable code, with clear separation between your application logic and the browser's 'ideosnycractic' APIs.

Pete Hodgson

February 04, 2015
Tweet

More Decks by Pete Hodgson

Other Decks in Programming

Transcript

  1. TEST-DRIVEN
    CLIENT-SIDE APPS
    Pete Hodgson
    @ph1 | [email protected]

    View full-size slide

  2. UNIT

    TESTING

    View full-size slide

  3. TEST
    DRIVEN
    DEVELOPMENT

    View full-size slide

  4. me me me
    Pete Hodgson
    Consultant at ThoughtWorks
    @ph1
    blog.thepete.net

    View full-size slide

  5. WRITE A

    FAILING TEST
    GET THE TEST
    TO PASS
    REFACTOR

    View full-size slide

  6. WRITE A

    FAILING TEST
    GET THE TEST
    TO PASS
    REFACTOR

    View full-size slide

  7. the

    backend
    the

    browser

    single-page
    javascript
    app
    REACT
    {JSON}

    View full-size slide

  8. {
    dest_name: “Richmond”,
    etd: 8,

    }
    Departure Domain Object
    {
    destination: “Richmond”,
    departing: “8 mins”
    }
    View Object
    presenter
    function

    View full-size slide

  9. var presentDeparture = function(departure){
    return {
    destination: departure.dest_name
    };
    };

    View full-size slide

  10. var departurePresenter = require('../../js/departure_presenter');
    !
    describe( 'Departure presenter', function(){
    it('presents the destination', function(){
    // Given
    var departure = {
    dest_name: "Ontario",
    etd: 10
    };
    // When
    var viewModel = departurePresenter(departure);
    // Then
    expect(viewModel).to.have.property('destination','Ontario');
    });
    });

    View full-size slide

  11. var departurePresenter = require('../../js/departure_presenter');
    !
    describe( 'Departure presenter', function(){
    it('presents the destination', function(){
    // Given
    var departure = {
    dest_name: "Ontario",
    etd: 10
    };
    // When
    var viewModel = departurePresenter(departure);
    // Then
    expect(viewModel).to.have.property('destination','Ontario');
    });
    });

    View full-size slide

  12. {
    dest_name: “Richmond”,
    etd: 8,

    }
    Departure Domain Object
    {
    destination: “Richmond”,
    departing: “8 mins”
    }
    View Object

    View full-size slide

  13. {
    dest_name: “Richmond”,
    etd: 8,

    }
    Departure Domain Object
    {
    destination: “Richmond”,
    departing: “8 mins”
    }
    View Object

    View full-size slide

  14. RAPID
    FOCUSED
    ACCURATE
    FEEDBACK

    View full-size slide

  15. 27
    TEST SCOPE

    View full-size slide

  16. TEST SCOPE
    DOM
    HTTP
    28

    View full-size slide

  17. 30
    ISOLATION
    test
    code

    View full-size slide

  18. presenter
    function
    test
    code

    ISOLATION

    View full-size slide

  19. departures
    gateway
    controller
    AJAX
    function
    “station-id”
    GET

    http://blah/station-id
    LIST OF
    DEPARTURE OBJECTS
    BIG BLOB

    OF JSON

    View full-size slide

  20. HTTP
    35
    ajax
    function

    View full-size slide

  21. 36
    fake
    ajax
    function

    View full-size slide

  22. 36
    fake
    ajax
    function

    View full-size slide

  23. departures
    gateway
    test
    code
    mock

    ajax fn

    View full-size slide

  24. departures
    gateway
    test
    code
    “station-id”
    “http://blah/station-id”
    mock

    ajax fn

    View full-size slide

  25. departures
    gateway
    test
    code
    CORRECTLY-PARSED
    DOMAIN OBJECT
    SOME JSON
    mock

    ajax fn

    View full-size slide

  26. it( 'parses the AJAX response as JSON', function(){
    // Given
    var fakeJson = '{ "some":"json" }';
    var fakeAjaxResponse = Q(fakeJson);
    var fakeAjaxFn = function(){
    return fakeAjaxResponse;
    };
    !
    var departuresGateway = createDeparturesGateway(fakeAjaxFn);
    !
    // When
    var departuresPromise = departuresGateway.fetchDeparturesFor('blah');
    !
    // Then
    return expect(departuresPromise)
    .to.eventually
    .deep.equal({some:"json"});
    });

    View full-size slide

  27. RAPID
    FOCUSED
    ACCURATE
    FEEDBACK

    View full-size slide

  28. mocha test runner
    chai assertion library
    gulp task runner, file watcher
    testem browser manager
    sinon stubbing/mocking
    chai-as-promised

    View full-size slide

  29. 45
    github.com/moredip/test-driven-react
    @ph1 | [email protected]
    http://slides.thepete.net

    View full-size slide