Skip to content

Instantly share code, notes, and snippets.

@Realtin
Last active May 21, 2016 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Realtin/04699d821dc58914ec4f70d6c4e9e929 to your computer and use it in GitHub Desktop.
Save Realtin/04699d821dc58914ec4f70d6c4e9e929 to your computer and use it in GitHub Desktop.

Testing React Compnents with Jasmine

Jasmine, a BDD Testing Framework for Javascript

BDD ?

describe('Customer', () => {              // Test Suite
  describe('Creation', () => {            // grouping related specs
    it('has a fitting title', () => {     // the actual spec!
      expect(comp.refs.title.innerText).toBe('New Customer');
    });
  });
  describe('Editing', () => {
    it('has a fitting title', () => {
      expect(comp.refs.title.innerText).toBe('Edit Customer');
    });
  });
});

is an asseartion libary!

expect(fn).toThrow(e);
expect(instance).toBe(instance);
expect(mixed).toBeDefined();
expect(number).toBeLessThan(number);
expect(array).toContain(member);
expect(string).toContain(substring);
expect(mixed).toEqual(mixed);
expect(mixed).toMatch(pattern);

// can be negated
expect(mixed).not.toMatch(pattern);

DRY your specs!

Setup and Teardown

beforeEach(() => {
  customerCreation = renderIntoDocument(
    <Customer {...intlData} />
  );
})
	  beforeEach(() => {
   store.set('user', {access_token: '7wetiqyoupeirutoyuighf'});
 });

 afterEach(() => {
   store.remove('user');
 });

spys

A spy can stub any function and tracks calls to it and all arguments.

describe('POSFormMixin', () => {
  spyOn(api, 'post');   

  it('does a post when submitting', () => {
     expect(api.post).toHaveBeenCalledWith({
      path: 'foods',
      entity: {
        data: {
          type: 'foods',
          attributes: {
            name: 'a',
            food: 'b'
          }
        }
       }
     });
  });
});

and.callThrough

and.returnValue

spyOn(api, 'get').and.returnValue({
  done: (cb) => {
    cb({response: JSON.stringify(countries)});
  }
});

async

Calls to beforeEach, it, and afterEach can take an optional single argument that should be called when the async work is complete.

    beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
  });

it("should support async execution of test preparation and expectations", function(done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });

render a Component

render a React component render components to a detached DOM node! -> can’t access lifecycle methods or events

header = renderIntoDocument(
  <Header {...intlData} authService={authService} />
)

Shallow rendering

-> perfect for testing in an isolation -> lower-level components cannot affect your test since they are not rendered at all. -> does not need a DOM!

It is the preferred way of testing React components suggested by React development team.

const renderer = React.addons.TestUtils.createRenderer();
renderer.render(<Page heading={headingElement} />);
const renderedTree = renderer.getRenderedOutput();

find the rendered children

returns a React Component!

const h1 = TestUtils.findRenderedDOMComponentWithTag(
   component, 'h1'
);
const h1s = TestUtils.scryRenderedDOMComponentsWithTag(
   component, 'h1'
);

ReactDOM.findDOMNode if you REALLY need to access the the corresponding native browser DOM element

expect(ReactDOM.findDOMNode(selectButton).type).toBe('button');

Simulate

Simulate has a method for every event that React understands

onScroll, onSelect, onDoubleClick, onChange onFocus, onCopy, onCut, onPaste ….

customerCityInput.value = 'bla';
Simulate.change(customerCityInput);
Simulate.submit(form);

Jest from Facebook

  • test runner and testing framework
  • built on Jasmine
  • mocks everything except the component we are testing
jest.unmock('../CheckboxWithLabel');

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import CheckboxWithLabel from '../CheckboxWithLabel';

describe('CheckboxWithLabel', () => {
  it('changes the text after click', () => {
    // Render a checkbox with label in the document
    const checkbox = TestUtils.renderIntoDocument(
      <CheckboxWithLabel labelOn="On" labelOff="Off" />
    );

    const checkboxNode = ReactDOM.findDOMNode(checkbox);

    // Verify that it's Off by default
    expect(checkboxNode.textContent).toEqual('Off');

    // ...
  });
});

Enzyme from airbnb

Testing utility for React

mimicking jQuery’s API for DOM

describe('<MyComponent />', () => {

  it('renders three <Foo /> components', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find(Foo)).to.have.length(3);
  });

  it('renders an `.icon-star`', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find('.icon-star')).to.have.length(1);
  });
});

helps with rendering (Static, Full and Shallow!)

const wrapper = shallow(<MyComponent />); // shallow rendering
const wrapper = mount(<Foo bar="baz" />); // Full DOM rendering
const wrapper = render(<Foo />); // renders static HTML

can be used with any asseartion libary (Jasmine!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment