bruderstein / unexpected-react

Plugin for http://unexpected.js.org to enable testing the full React virtual DOM, and also the shallow renderer
http://bruderstein.github.io/unexpected-react
MIT License
187 stars 19 forks source link

`to have rendered` not ignoring attributes #36

Closed ezmiller closed 7 years ago

ezmiller commented 7 years ago

I'm encountering some confusing behavior with the to have rendered assertion. It's my understanding from the documents that this assertion should ignore unspecified attributes, but I'm getting the following diff form a test failure:

<div className="app-container">
  <div className="car-header">
    <Connect(withRouter(CarForm)) />
    <SearchTabs routes={[
      { path: 'search', label: 'Keyword Search' },
      { path: 'search-subsystem', label: 'Vehicle Subsystems' },
      { path: 'search-oe-toc', label: 'OE Table of Contents' }
    ]}
       selectedFn={function bound topNavSelected() { /* native code */ }} // expected function bound topNavSelected() { /* native code */ }
                                                                          // to equal function selectedFn() {}
    />
  </div>
  <div className="car-view-router-content" />
</div>

for a test that looks like this:

    const wrapper = shallow(<ExistingApp />);
    expect(wrapper.node, 'to have rendered', (
      <div className="app-container">
        <div className="car-header">
          <CarForm />
          <SearchTabs />
        </div>
        <div className="car-view-router-content" />
      </div>
    ));
  });

I think possibly I'm misunderstanding how this should be working. But I also wonder if there's a functional problem here in the assertion. Could it be happening because I'm using enzyme with your library instead of React TestUtils directly?

bruderstein commented 7 years ago

It looks like you've got some defaultProps on the SearchTabs component.

Rather than using the original component in the assertion, you can just use something that reports the same name. A one-line function SearchTabs() { return null; } should do.

Also, you don't need to use enzyme or the TestUtils to render it now (since 3.5.0) just use either 'when rendered', or the shortcut 'to render as' which renders your component with the shallow renderer and then does a to have rendered on it.

function SearchTabs() { return null }

    expect(<ExistingApp />, 'to render as',
      <div className="app-container">
        <div className="car-header">
          <CarForm />
          <SearchTabs />
        </div>
        <div className="car-view-router-content" />
      </div>
    );
bruderstein commented 7 years ago

Please let me know if that fixes it so we can close the issue.

ezmiller commented 7 years ago

Hmmm. Technically it does. But I'm not entirely happy with the solution. Seems a bit hacky, and defaultProps are pretty common. Thanks for your help.