2015-06-18 5 views
8

Скажу, у меня есть компонент, который выглядит следующим образом:Sinon.js - заглушка Реактивировать функцию компонента перед созданием компонента?

var React = require('react/addons'); 

var ExampleComponent = React.createClass({ 
    test : function() { 
     return true; 
    }, 
    render : function() { 
     var test = this.test(); 
     return (
      <div className="test-component"> 
       Test component - {test} 
      </div> 
     ); 
    } 
}); 

module.exports = ExampleComponent; 

В моем тесте, я мог бы сделать этот компонент с помощью TestUtils, затем гасит метод следующим образом:

var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>); 
sinon.stub(renderedComponent, 'test').returns(false); 
expect(renderedComponent.test).toBe(false); //passes 

Но есть способ, которым я мог бы сказать Синону, автоматически отключать функцию компонента каждый раз, когда создается экземпляр этого компонента? Пример:

sinon.stubAll(ExampleComponent, 'test').returns(false); //something like this 
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>); 
expect(renderedComponent.test).toBe(false); //I'd like this to pass 

Если это невозможно, существует ли потенциальное решение, которое подходит для обеспечения функциональности, которую я ищу?

ответ

3

Я нашел решение проблемы.

Чтобы уточнить, моя проблема в том, что я хотел бы заглушить функции, принадлежащие дочерним компонентам, которые отображаются под родительским компонентом. Так что-то вроде этого:

parent.js

var Child = require('./child.js'); 
var Parent = React.createClass({ 
    render : function() { 
     return (
      <div className="parent"> 
       <Child/> 
      </div> 
     ); 
    } 
}); 
module.exports = Parent; 

child.js

var Child = React.createClass({ 
    test : function() { 
     return true; 
    }, 
    render : function() { 
     if (this.test) { 
      throw('boom'); 
     } 
     return (
      <div className="child"> 
       Child 
      </div> 
     ); 
    } 
}); 
module.exports = Child; 

Если бы я должен был использовать TestUtils оказывать Родитель в одном из моих тестов, было бы выбросьте ошибку, которую я хотел избежать. Поэтому моя проблема заключалась в том, что мне нужно было отключить функцию Child's test до ее создания. Затем, когда я делаю Родитель, Ребенок не взорвется.

Ответ предоставлен не совсем так, поскольку родитель использует require(), чтобы получить конструктор ребенка. Я не знаю, почему, но из-за того, что я не могу погасить окурок прототип ребенка в моем тесте и ожидать, что тест пройти, например, так:

var React = require('react/addons'), 
    TestUtils = React.addons.TestUtils, 
    Parent = require('./parent.js'), 
    Child = require('./child.js'), 
    sinon = require('sinon'); 

describe('Parent', function() { 
    it('does not blow up when rendering', function() { 
     sinon.stub(Child.prototype, 'test').returns(false); 
     var parentInstance = TestUtils.renderIntoDocument(<Parent/>); //blows up 
     expect(parentInstance).toBeTruthy(); 
    }); 
}); 

Я был в состоянии найти решение, которое соответствует моим потребности. Я переключил свою тестовую структуру с Mocha на Jasmine, и начал использовать jasmine-react, что обеспечило несколько преимуществ, в том числе возможность отключить функцию класса до того, как он будет создан. Ниже приведен пример рабочего решения:

var React = require('react/addons'), 
    Parent = require('./parent.js'), 
    Child = require('./child.js'), 
    jasmineReact = require('jasmine-react-helpers'); 

describe('Parent', function() { 
    it('does not blow up when rendering', function() { 
     jasmineReact.spyOnClass(Child, 'test').and.returnValue(false); 
     var parentInstance = jasmineReact.render(<Parent/>, document.body); //does not blow up 
     expect(parentInstance).toBeTruthy(); //passes 
    }); 
}); 

Надеюсь, это поможет кому-то еще с подобной проблемой. Если у кого есть какие-то вопросы, я был бы рад помочь.

13

Вам необходимо будет перезаписать ExampleComponent.prototype вместо . - конструктор. Локальные методы, такие как test(), сохраняются в нем prototype.

sinon.stub(ExampleComponent.prototype, 'test').returns(false); 
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>); 
expect(renderedComponent.test).toBe(false); //passes 
+0

Спасибо за ответ. Хотя, похоже, это работает в некоторых случаях, это не совсем то, что я ищу. Я, вероятно, должен был быть более конкретным. У меня есть родительский и дочерний компонент, а дочерний компонент визуализируется внутри метода «render» родительского компонента. Родитель использует 'require()' для получения конструктора, и, похоже, не существует способа переопределить прототип ребенка внутри моего теста. Имеет ли это смысл? Если вы захотите, я могу обновить свой вопрос. –

+0

Было бы здорово, если бы вы могли расширить вопрос на примере. – Victor

+0

Я нашел рабочее решение, но я все равно буду награждать вас щедростью. –

Смежные вопросы