Как проверить, содержит ли компонент React другой компонент со шуткой?

Я пытаюсь использовать jest-cli для проверки того, содержит ли один компонент реакции другой компонент в нем. Мне трудно понять, как это сделать.

Вот мои компоненты:

Компонент DesignerPage

[...]
var TopBar = require('../components/layout/TopBar.js');

var DesignerPage = React.createClass({
  getInitialState: function() {
    var state = {
    };
    return state;
  },
  render: function() {
    return (
      <div> 
        <TopBar />
      </div>
    )
  }
});

module.exports = DesignerPage;

Компонент TopBar

/** @jsx React.DOM */
var React = require("react");

var TopBar = React.createClass({
    render: function() {
        return (
            <nav className="top-bar">
            </nav>
        );
    }
});

module.exports = TopBar;

Теперь я хочу проверить, содержит ли компонент DesignerPage компонент TopBar. Вот что я думаю, должен работать:

/** @jsx React.DOM */
jest.dontMock('../../src/js/pages/DesignerPage.js');
describe('DesignerPage', function() {
  it('should contain a TopBar', function() {
    var React = require('react/addons');
    var DesignerPage = require('../../src/js/pages/DesignerPage.js');
    var TestUtils = React.addons.TestUtils;

    // Render a DesignerPage into the document
    var page = TestUtils.renderIntoDocument(
      <DesignerPage />
    );

    // Verify that a TopBar is included
    var topbar = TestUtils.scryRenderedComponentsWithType(page, 'TopBar');
    expect(topbar.length).toBe(1);
  });
});

Но это не проходит...: (

$ ./node_modules/jest-cli/bin/jest.js DesignerPage
Found 1 matching test...
 FAIL  __tests__/pages/DesignerPage-test.js (4.175s)
● DesignerPage › it should contain a TopBar
  - Expected: 0 toBe: 1
        at Spec.<anonymous> (__tests__/pages/DesignerPage-test.js:16:27)
        at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
1 test failed, 0 test passed (1 total)
Run time: 6.462s

Ответы

Ответ 1

Я не запускаю данный код, но строка:

var topbar = TestUtils.scryRenderedComponentsWithType(page, 'TopBar');

выглядит подозрительно для меня. docs кажется, что вы должны передать componentClass вместо строки.

Я не вижу, как он может использовать строку для идентификации типа компонента. Он может потенциально использовать displayName, чтобы идентифицировать его по строкам, но я сомневаюсь, что он это сделает.

Я считаю, что вы, вероятно, хотите этого:

var TopBar = require('../../src/js/pages/DesignerPage');
var topbar = TestUtils.scryRenderedComponentsWithType(page, TopBar);

Ответ 2

Я столкнулся с аналогичной ситуацией, когда мне нужно было проверить, был ли обработан дочерний компонент или нет. Насколько я понимаю, шутка издевается над всеми необходимыми модулями, кроме тех, где вы указываете не. Таким образом, в вашем случае дочерний компонент Topbar будет высмеиваться, что заставляет меня предположить, что обработанная DOM не будет такой, как ожидалось.

Что касается проверки того, был ли обработан дочерний компонент, я бы сделал

expect(require('../../src/js/component/layout/TopBar.js').mock.calls.length).toBe(1)

который в основном проверяет, был ли вызван вымышленный дочерний компонент или нет.

Если вы действительно хотите протестировать компонент TopBar на этом уровне, вы, вероятно, захотите установить

jest.dontMock('../../src/js/component/layout/TopBar.js') 

а также сообщить jest, чтобы не издеваться над компонентом TopBar, так что рендеринг DOM включает в себя вывод из компонента TopBar.

Я создал репо на основе вашего примера в Github, который тестирует дочерние компоненты. Есть два тестовых файла: один тест для дочерних компонентов, которые насмехаются, а другой не издевается над дочерним компонентом.