r/reactjs•
PMMN

Questions regarding Jest, Enzyme, and best practices

Hi,

I'm trying to learn testing in react, and had come across some questions.

My project uses MobX, SemanticUI React, and Firebase.

  • Shallow rendering won't render <Button /> components that I'm using off of semantic ui react, because it's one level deep right? I'm trying to simulate a click on a submit button, and I'm using wrapper.findWhere(node => node.type() === 'button' && node.contains('Submit')) to find the button to click. But if I'm using shallow(), I can't access the properties that I'm using and I have to use mount?

  • In above case, it's better to test how the click changes the view, and not how it changes the internal state of the component right?

  • What are some good things to test in React, knowing that the structure and the view of the rendered html structure might change due to design revamp or whatnot?

Thank you

Posted May 19, 2019, 8:01 PM UTC

13
Canenald•

Jest and Enzyme work best for unit testing. In that case, you want to test a component and what it renders when you change props and optionally call its method. You don't care about what its children do, only if they are rendered and with which props.

​

More precisely, to address your questions:

  • Simulating events is usually excessive, not to mention you are doing it on a child component, not the component you are testing. Even on the tested component, it's perfectly enough to call the method that's bound as click event handler. Look at it this way: If you simulate a click vs call the method, what are you testing? That event handler binding works fine? You are testing React and JavaScript, not your own code.
  • Yes, if you want to unit test, the fact that your intended tests require mount() instead of shallow() usually means you are trying to do something wrong. In this case, you should test your component, not the buttons in it. Semantic UI should have its own tests, and if you are opting to use it you should also trust those tests :)
  • If you are unit testing, you should make sure you are unit testing. This in its own will solve most of your problems. That's not to say unit tests are all-powerful or that you should be even unit testing. Make your choice and stick to it. If you want to do end-to-end UI tests, there are better choices than Jest and Enzyme out there, for example Nightwatch or Cypress.
  • ​

My approach to unit testing new components goes something like the following:

  • First test case checks the component with minimal required props.
  • Each prop change or usage of a non-required prop is a new test case
  • Make sure you hit all combinations that cause different behavior. Conditional rendering? Test both scenarios. Event handler methods? Test each of them separately.
  • When you test that something happens when you add an optional prop, add an assertion to the first test case to check that it doesn't happen when the prop is not passed.
  • If you think you need mount() think again. Only use it if you're absolutely sure you need it.
2
nikola1970•

Check react-testing-library and it’s philosophy.

1
Skeith_yip•

It really depends on what you are trying to test. really. Do you want to test the DOM event or do you just wanna test your own logic?

You can do:

expect(wrapper.find(Counter).props().value).toBe(0);
// if you only have a single button
wrapper.find(Button).props().onClick(e);
expect(e.preventDefault).toHaveBeenCalledTimes(1);
// e should be something like e: { preventDefault: jest.fn()};

// usually I don't check the internal state unless there's code that specifically need to do so
// example when button is clicked, the counter is increased
expect(wrapper.find(Counter).props().value).toBe(1);

Of course you can always go full gung-ho and render the DOM and run through the DOM events. react-testing-library is a good place to do that.

1