React-helmet: How to unit test an application that uses Helmet?

Created on 16 Aug 2016  ยท  7Comments  ยท  Source: nfl/react-helmet

Is there a way to unit test an application that uses Helmet? The problem is that Helmet sets things outside the current component...

Thanks very much for your help!

Most helpful comment

You'll need to use mount, which will recreate a DOM for you so you can query it in your test. You might also need to query the title in the mounted component itself (wrapper.find("title")).

All 7 comments

@templth Thanks for your interest in Helmet. Yes, true, Helmet only deals with side effects to the document head. There a couple ways to approach testing. You can certainly set assertions that check for conditions in your document head. You can also utilize onChangeClientState callback to monitor state changes as Helmet processes them.

I hope that helps.

@cwelch5 Thanks very much Chris for your answer!

Here is a fake component using Helmet I want to test:

class FakeComponent {
    render() {
        return (
            <div>
                <Helmet
                    onChangeClientState={ this.logChangeClientState }
                    title={"Test Title"}
                    defaultTitle={"Fallback"}
                />
            </div>
        )
    }
    logChangeClientState() {
        console.log('logChangeClientState');
    }
}

and here is the test I implemented (with Mocha and Enzyme):

it('fake test', function() {
    let wrapper = shallow(
        <div><FakeComponent/></div>
    );
    expect(document.title).to.equal('Test Title');
});

document.title is empty and logChangeClientState isn't called. I think that I missed something.

Thanks very much for your help!

It seems like Helmet is not getting rendered. What does shallow do? Is it like this - https://facebook.github.io/react/docs/test-utils.html#shallow-rendering? If that's the case, from how I'm reading this, it only renders the first level, and may not be rendering Helmet. Try doing a ReactDOM.render of the Helmet component and see if that helps.

You'll need to use mount, which will recreate a DOM for you so you can query it in your test. You might also need to query the title in the mounted component itself (wrapper.find("title")).

Thanks very much, guys! It works fine ;-)

Does this still work?
Somehow the following fails for me, and it looks basically the same:

// src/nav.spec.js
import React from "react";
import Helmet from "react-helmet";
import { mount } from "enzyme";
import "should";
import "should-enzyme";


it("foo", () => {
  const page = mount(
    <div>
      <Helmet>
        <title>foobar</title>
      </Helmet>
    </div>);
  document.title.should.eql("foobar");
});

fails with:

 FAIL  src/nav.spec.js
  โ— foo

    AssertionError: expected '' to equal 'foobar'

      13 |       </Helmet>
      14 |     </div>);
    > 15 |   document.title.should.eql("foobar");
         |                         ^
      16 | });
      17 |
      18 |

      at Assertion.fail (node_modules/should/cjs/should.js:275:17)
      at Assertion.value (node_modules/should/cjs/should.js:356:19)
      at Object.eql (src/nav.spec.js:15:25)

Found an answer to this in the following SO question: https://stackoverflow.com/questions/44073960/unit-testing-react-helmet-code

    const wrapper = mount(<Metadata/>);
    // this will return all the markup assigned to helmet
    // which will get rendered inside head.
    const helmet = Helmet.peek();
    expect(helmet.title).to.equal("title");
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bassarisse picture bassarisse  ยท  3Comments

mattecapu picture mattecapu  ยท  4Comments

bradbarrow picture bradbarrow  ยท  4Comments

tinynumbers picture tinynumbers  ยท  5Comments

namnm picture namnm  ยท  4Comments