Using HTML fixtures

Continuing with the development of the NewInvestmentView component, we can write some basic acceptance criteria:

  • NewInvestmentView should allow the input of the stock symbol
  • NewInvestmentView should allow the input of shares
  • NewInvestmentView should allow the input of the share price

There are many more, but these are a good start.

Create a new spec file for this component, in the new file spec/NewInvestmentViewSpec.js and we can start to translate those specs:

describe("NewInvestmentView", function() {
  it("should allow the input of the stock symbol", function() {
  });

  it("should allow the input of shares", function() {
  });

  it("should allow the input of the share price", function() {
  });
});

But before we can start to implement these, we must first understand the concept of HTML fixtures.

Test fixtures provide the base state in which the tests run. It could be a class instantiation, the definition of an object, or a piece of HTML. In other words, to test JavaScript code that handles a form submission, you need to have the form available when running the tests. The HTML code containing the form is an HTML fixture.

One way to handle this requirement is by manually appending the required DOM element inside a setup function:

beforeEach(function() {
  $('body').append('<form id="my-form"></form>'),
});

And removing it during teardown:

afterEach(function() {
  $('#my-form').remove();
});

Otherwise the spec would be appending a lot of garbage inside the document, and it could interfere with the results of other specs.

Tip

It is important to know that specs should be independent and that they can be run in any particular order. So as a rule, treat your specs completely in isolation from each other.

A better approach is to have a container in the document where we always put the HTML fixtures:

<div id="html-fixtures">
</div>

And change the code to:

beforeEach(function() {
  $('#html-fixtures').html('<form id="my-form"></form>'),
});

That way, the next time a spec runs, it automatically overwrites the previous fixture with its own.

But this can soon escalate into an incomprehensible mess, as the fixtures get more complex:

beforeEach(function() {
  $('#html-fixtures').html('<form id="new-investment"><h1>Newinvestment</h1><label>Symbol:<input type="text" class="new-investment-stock-symbol" name="stockSymbol"value=""></label><input type="submit" name="add"value="Add"></form>'),
});

Wouldn't it be great if this fixture could be loaded from an external file? That is exactly what the Jasmine jQuery extension does, with its HTML Fixture module.

We can place that HTML code in an external file and load it in the document with a simple call to loadFixtures, passing the fixture file path:

beforeEach(function() {
  loadFixtures('MyFixture.html'),
});

The extension looks for a file spec/javascripts/fixtures/MyFixture.html, and loads its content inside a container:

<div id="jasmine-fixtures">
  <form id="new-investment">
    <h1>New investment</h1>
    <label>
      Symbol:
      <input type="text" class="new-investment-stock-symbol"name="stockSymbol" value="">
    </label>
    <input type="submit" name="add" value="Add">
  </form>
</div>

We can also use another of the extension's global functions, to recreate the first example. The setFixtures(html) accepts a parameter with the content to be placed in the container:

beforeEach(function() {
  setFixtures('<form id="my-form"></form>'),
});

Other available functions are:

  • appendLoadFixtures(fixtureUrl[, fixtureUrl, …]): Instead of overwriting the content of the fixture container, this appends it
  • readFixtures(fixtureUrl[, fixtureUrl, …]): This reads a fixture content, but instead of appending it to the document, it returns a string with its contents
  • appendSetFixtures(html): This is the same as the appendLoadFixtures, but with an HTML string instead of a file

The Jasmine jQuery fixture module caches each file, so we can load the same fixture multiple times without penalty in the test suite speed.

It loads the fixtures using AJAX, and sometimes a test might want to modify the inner workings of JavaScript or jQuery AJAX as we will see in Chapter 6, Light Speed Unit Testing, which would break the loading of a fixture. A workaround for this issue, is to preload the required fixtures on the cache using the preloadFixtures() function.

The preloadFixtures(fixtureUrl[, fixtureUrl, …]) loads one or more files in the cache without appending them to the document.

There is an issue though, while using HTML fixtures with Chrome. Jasmine jQuery loads the HTML fixtures using AJAX, but because of the Same Origin Policy, Chrome blocks all AJAX requests when opening the SpecRunner.html with a file:// protocol.

A solution to this problem is to serve the spec runner through an HTTP server, as described in Chapter 4, Asynchronous Testing – AJAX.

For now, the easiest solution might be to use another browser, such as Firefox.

More details on this Chrome issue can be seen at this GitHub ticket:

https://github.com/velesin/jasmine-jquery/issues/4

Back to the NewInvestmentView component, we can start the development of the spec with the help of this HTML fixture plugin.

Based on the mockup interface we can create a new HTML fixture called spec/fixtures/NewInvestmentView.html

<form id="new-investment">
  <h1>New investment</h1>
  <label>
    Symbol:
    <input type="text" class="new-investment-sti ock-symbol"name="stockSymbol" value="">
  </label>
  <label>
    Shares:
    <input type="number" class="new-investment-shares"name="shares" value="0">
  </label>
  <label>
    Share price:
    <input type="number" class="new-investment-share-price"name="sharePrice" value="0">
  </label>
  <input type="submit" name="add" value="Add">
</form>

And because we are saving this fixture not at the plugin's default path, we need to add a new configuration at the end of the SpecHelper.js file:

jasmine.getFixtures().fixturesPath = 'spec/fixtures';

In the spec, add the call to load the fixture:

describe("NewInvestmentView", function() {
  beforeEach(function() {
    loadFixtures('NewInvestmentView.html'),
  });
});

And finally, add both the spec and the source to the runner:

<script type="text/javascript"src="src/NewInvestmentView.js"></script>
<script type="text/javascript"src="spec/NewInvestmentViewSpec.js"></script>
..................Content has been hidden....................

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