Chapter 6. Light Speed Unit Testing

In the Chapter 4, Asynchronous Testing – AJAX, we have seen how including AJAX testing in the application can increase the complexity of the tests. In the example, we created a server where the results were predictable. It was basically a complex test fixture. And even though we could have used a real server implementation, it would increase the complexity of the test even more, try changing the state of a server with a database or third-party services from the browser, it is not an easy or scalable solution.

There is also the impact on productivity; these requests take time to process and to transmit, which hurts the quick feedback loop that unit testing usually provides.

You can also say that these specs are testing both the client and the server code, and therefore could not be considered as unit tests, but rather as integration tests.

A solution to all these problems is to use either Stubs or Fakes in place of the real dependencies of the code. So instead of making a request to the server, we use a test double of the server, inside the browser.

We are going to use the same example from Chapter 4, Asynchronous Testing – AJAX, and rewrite it using different techniques.

Jasmine Stubs

We have already seen some use cases for Jasmine spies. Remember that a spy is a special function that records how it was called. You can think of a Stub as a Spy with behavior.

We use Stubs whenever we want to force a specific path in our specs, or replace a real implementation for a simpler one.

Let's revisit the example of the acceptance criteria, "Stock when fetched, should update its share price", by rewriting it using Jasmine Stubs.

Since we know that the stock's fetch function is implemented using the $.getJSON function:

Stock.prototype.fetch = function(parameters) {
  $.getJSON(url, function (data) {
    that.sharePrice = data.sharePrice;
    success(that);
  });
};

We could use the spyOn function to set up a spy on the getJSON function:

describe("when fetched", function() {
  beforeEach(function() {
    spyOn($, 'getJSON').andCallFake(function(url, callback) {
      callback({ sharePrice: 20.13 });
    });
    stock.fetch();
  });

  it("should update its share price", function() {
    expect(stock.sharePrice).toEqual(20.13);
  });
});

But this time we will use the andCallFake function to set a behavior to our spy (by default a spy does nothing and returns undefined). We make the spy invoke its callback parameter with an object response ({ sharePrice: 20.13 }).

Later, at the expectation, we use the toEqual assertion to verify that the stock's sharePrice has changed.

To run this spec, you no longer need a server to make the requests to, which is a good thing, but there is one issue with this approach. If the fetch function gets refactored to use $.ajax instead of $.getJSON, then the test will fail. A better solution, provided by the Sinon.JS library, is to Stub the browser's AJAX infrastructure instead, so the implementation of the AJAX request is free to be done in different manners.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.103.204