How do I use Jest to test a React view wired to store?

1.7k views Asked by At

I have a React view that communicates with a store. I've successfully tested views and stores separately, but not in combination.

I followed the structure documented here but received a TypeError. It looks like Jest is trying to register the store as a component even if I use dontMock.

Using Jest CLI v0.2.0
 PASS  __tests__/unit/spec/stores/ViewStore-spec.js (0.248s)
 FAIL  __tests__/unit/spec/components/View-spec.react.js (0.942s)
undefined
● View › it defaults to zero unread
  - TypeError: /Users/matnorri/dev/projects/matnorri/web-client/src/app/scripts/components/View.react.js: /Users/matnorri/dev/projects/matnorri/web-client/src/app/scripts/stores/ViewStore.js: Cannot call method 'register' of undefined
        at /Users/matnorri/dev/projects/matnorri/web-client/src/app/scripts/stores/ViewStore.js:43:31
        at Object.runContentWithLocalBindings (/Users/matnorri/dev/projects/matnorri/web-client/node_modules/jest-cli/src/lib/utils.js:357:17)
        ...

I've included what I believe is the relevant code below, but can provide it in its entirety if necessary.

View Jest Test

jest.dontMock('../../../../src/app/scripts/components/View.react');
jest.dontMock('../../../../src/app/scripts/stores/ViewStore');

describe('View', function() {

  var React;
  var TestUtils;
  var ViewComponent;
  var View;

  beforeEach(function() {
    React = require('react/addons');
    TestUtils = React.addons.TestUtils;
    ViewComponent =
      // Tried both lines with same effect.
      // require('../../../../src/app/scripts/components/View.react.js');
      require('../../../../src/app/scripts/components/View.react');
    View = TestUtils.renderIntoDocument(<ViewComponent />);
  });

  it('defaults to zero unread', function() {
    View._toString = jest.genMockFunction();
    View._onChange();
    expect(View.state.unread).toBe(0);
  });
});

Thank you!

1

There are 1 answers

4
Stefan On BEST ANSWER

Answer to your question

I ran into this issue too and not mocking object-assign solved the issue for me. Add jest.dontMock('object-assign'); to your spec file. This will solve the problem.

// View Jest test
jest.dontMock('../../../../src/app/scripts/components/View.react');
jest.dontMock('../../../../src/app/scripts/stores/ViewStore');

To mock or not to mock

Some more information about when to "mock or not to mock" can be found on the Jest documentation website.

Jest modifies the default behavior of the "require" method and implements it's own require method. This way they are able to mock every function inside a file. So if you want something to really work (like with a store) you should not mock the file.

In your case you're not mocking the ViewStore so every function on this Store will be called. Because you didn't not mock object-assign the object assign function doesn't work. This way the ViewStore isn't created the right way (it returns undefined) and the test throws the error Cannot call method 'register' of undefined as your assign function didn't work, because it was mocked.

Again; If you read through the documentation on the Jest website, you'll find a detailed description about when to "mock or not to mock".


Extra info

I recommend to add "object-assign" and other commonly used modules (like lodash/underscore) to the unmockedModulePathPatterns in your test config. More information about this: https://facebook.github.io/jest/docs/api.html#config-unmockedmodulepathpatterns-array-string