ReactJS - Use a Custom Dummy Instead of nock When Possible

Published Aug 31, 2017
ReactJS - Use a Custom Dummy Instead of nock When Possible

I just realized today that due to the type of tests I had in my spec, and the fact that our action creators are passed to our container via mapDispatchToProps, that I didn't even need to nock calls to isolate my tests. This is not always the case, sometimes it makes sense to nock but in this case I didn't need to.

Below is an integration test on existing legacy code. I call it an isolated integration test because these tests don't make calls to real things (real API calls over the network, hit a real DB, etc.). It's also an integration test because it tests several components as a unit. I'm using enzyme mount() for integration tests.

Example - Mock Collaborator (action creator) with a Dummy

Here, notice that fetchSearch() is passed to the connected container via mapDispatchToProps. Well, this means I can inject my own dummy as a prop from my test:

some.spec.js

import { createStore, expect, mount, nock, Provider, React } from 'test/test.helpers';
import { Search } from 'app/components/containers/Search';

describe('Search', () => {
  describe('Successful', () => {
    let search;

    beforeEach(() => {
      const reducers = require('config/reducers').default;
      // note: stub could/should be refactored to reduce repetition
      const panels = {
        member: [{
          headline: 'New',
          customViews: [
            {
              name: 'Hockey',
              url: 'https://fakehost/items',
            },
            {
              name: 'Football',
              url: 'https://fakehost/items',
            }],
        },
        {
          headline: 'Old',
          customViews: [
            {
              name: 'Hockey',
              url: 'https://fakehost/items',
            },
            {
              name: 'Football',
              url: 'https://fakehost/items',
            }],
        }],
      };

      search = mount(
        <Provider store={createStore(reducers, {})}>
          <Search
            fetchSearch={() => {}} //send in a dummy
            panels={panels}
            ...whatever else
          />
        </Provider>);
    });

    ...
    it('contains category tabs with items', () => {
      const items = search.find('.ft-search-tab');
      expect(items.length).to.equal(2);
    });
  });

  // I don't need to nock (this time)!!  - Remove this helper!
  const mockGet = (url, uri, responseCode, responseBody) => {
    nock(url)
      .matchHeader('accept', 'application/json, text/plain, */*')
      .get(uri)
      .reply(responseCode, responseBody);
  };
});

So what I'm referring to is this: fetchSearch={() => {}}. My container therefore ends up calling this, not the action creator.

react-redux Connected Container

export default class Search extends Component {
...
  componentDidMount() {
    ...
      this.props.fetchSearch(); // calls my dummy (ah! I forgot about this!)
    ...
  }

  render() {
      ...
    );
  }
}

export default connect(null, {
  fetchSearch,
  ...
})(Search)

Keep in mind I could also send in the stub data by just returning it from the dummy as well:

fetchSearch={() => { panels }}

depending how your react component works with it, this may or may not make sense or work. If it does, then great, one less line of code in your test.

Sometimes you get tunnel vision and get so used to using something like nock that so it's just good every once-in-a-while to verify what your tests are truly doing by stepping through or changing prod code to verify that the tests are indeed good ones.. or doing things in the way you think they are.

Final Note: Remember, you don't need a mocking framework for pretty much almost everything. I don't really use one except for rare occasions where sinon and nock might be useful. Otherewise I don't like to invite a lot of magic into my code and usualy I can get away with my own cusotm mocks which end up being super simple and easy in a lot of cases.

I'm using mocha here with enzyme, because it works jsut fine, Jest is a scam).

Discover and read more posts from Dave Schinkel
get started
Enjoy this post?

Leave a like and comment for Dave

1