Подтвердить что ты не робот

Стабилизация компонента компонента React с помощью Sinon

Я пытаюсь заглушить компонент React для целей тестирования:

var Comp = React.createClass({
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div(null, "foo");
  }
});

var stub = sinon.stub(Comp.type.prototype, "plop");
React.addons.TestUtils.renderIntoDocument(Comp());
sinon.assert.called(stub); // throws

Это, к сожалению, печатает "plop" на консоли... и утверждение терпит неудачу.

Примечание. Непосредственно опускание метода объекта спецификации работает, но затем вам нужно экспортировать конструктор компонента и спецификацию отдельно, чтобы они оба были доступны в тестах... Кроме того, вам нужно будет заглушить спецификацию до создания компонента класс; не очень удобно:

var CompSpec = {
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div("foo");
  }
};

var stub = sinon.stub(CompSpec, "plop");
var Comp = React.createClass(CompSpec);
React.addons.TestUtils.renderIntoDocument(Comp());

// plop() is properly stubbed, so you can
sinon.assert.called(stub); // pass

Можете ли вы придумать еще одну стратегию, чтобы легко заглушить метод компонента React?

4b9b3361

Ответ 1

У вас работает функция React автоматической привязки, которая кэширует .bind(this), который обернут вокруг ваших методов класса. Вы можете заставить свой код работать, запустив кешированную версию метода в React __reactAutoBindMap:

var Comp = React.createClass({
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div(null, "foo");
  }
});

// with older versions of React, you may need to use
// Comp.type.prototype instead of Comp.prototype
var stub = sinon.stub(Comp.prototype.__reactAutoBindMap, "plop");  // <--
React.addons.TestUtils.renderIntoDocument(React.createElement(Comp));
sinon.assert.called(stub);  // passes

Ответ 2

Какую тестовую структуру вы используете?

Если вы используете жасмин, я нашел jasmine-react, чтобы быть полезной библиотекой для проверки методов React, а также для замены компонентов тестовыми заглушками.

В этом случае вы можете легко отслеживать свой метод вне определения компонента.

//Component Definition
var Comp = React.createClass({

    displayName: "Comp",

    plop: function() {
       console.log("plop");
    },

    render: function() {
       this.plop();
       return React.DOM.div(null, "foo");
    }
});

//test
it("should call plop method on render", function(){
   //spy on method
   jasmineReact.spyOnClass(Comp, "plop");
   React.addons.TestUtils.renderIntoDocument(Comp());
   expect(Comp.plop).toHaveBeenCalled();
})

jasmineReact.spyOnClass возвращает обычный шпион-жасмин, который вы можете использовать для отслеживания вызовов и его аргументов.

Если вы хотите на самом деле заглушить метод и заставить его что-то вернуть, вы можете сделать что-то вроде jasmineReact.spyOnClass(Comp, "plop").andReturn('something')

В качестве альтернативы Facebook недавно запустил тестовую среду Jest (также имеет жасмин как зависимость), которую они используют для тестирования компонентов React. Компонентные методы можно легко обрезать с использованием этой структуры. Это похоже на то, что стоит проверить, но, возможно, немного больше, когда вы пишете свои компоненты в модулях commonJS