2017-01-03 6 views
1

У меня есть Реагировать компонент со следующим кодом:Test componentWillUnmount() удаляет класс из тела

componentWillUnmount() { 
    document.body.classList.remove('isPreloaded') 
    } 

Я имею body тег с isPreloaded классом, Preloader HTML и стилями для него сначала в index.html (как критические вещи). Когда приложение загружено, компонент Preloader отображается в тело (для пользователя ничего не меняется). И когда данные поступают с сервера, Preloader удаляется. Конечно, я должен удалить класс isPreloaded, так как он делает тело необратимым.

Вышеприведенное описание напрямую не связано с моим вопросом, но я решил добавить его, чтобы исключить такие комментарии, как «Это плохая практика» или подобное.

Так что я хочу протестировать это поведение. Чтобы гарантировать, что это работает, как ожидается, я должен сделать этот компонент внутри <body> с классом isPreloaded и сохранить его в переменной, пусть это будет container. Тогда я должен проверить, что этот класс существует в container. И во втором тесте я должен отключить компонент из контейнера и проверить, что класс исчез.

Это примерно то, что я хочу добиться:

describe('<Preloader />',() => { 
    const container = mount(<body className='isPreloaded'><Preloader /></body>) 

    it('should be rendered with `isPreloaded` class',() => { 
    expect(container.find('isPreloaded').length).toBe(1) 
    }) 

    ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(container).childNode) 

    it('should remove `isPreloaded` class from body when unmounted',() => { 
    expect(container.find('.isPreloaded').length).toBe(0) 
    }) 
}) 

Но это не работает. Первое утверждение возвращает 0 вместо 1 и поэтому терпит неудачу. Второй один выдает следующее сообщение об ошибке:

Invariant Violation: findDOMNode was called on an unmounted component.

+0

среагировать версию ?? – Codesingh

+0

@Codesingh 15.4.1 –

ответ

0

ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(container).childNode) является асинхронной функцией, так что вы должны сделать, это: -

setTimeout(function() { 
    ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(container).childNode) 
}, 3000 

вы можете также добавить слушатель componentWillUnmount().

для it использования выпуска этого:

let {TestUtils} = React.addons; 
this.container = TestUtils.renderIntoDocument(<body  className='isPreloaded'><Preloader /></body>) 
this.renderedDOM =() => React.findDOMNode(this.container); 

it('should be rendered with `isPreloaded` class',() => { 
    expect(this.renderedDOM().children.length).toEqual(1); 
    }) 
+0

Возможно, достаточно использовать 'setImmediate' (или' process.nextTick') один или два раза. 'setImmediate (_ => setImmediate (func))' будет запускать 'func' два основных цикла цикла после вызова. К тому времени обратные вызовы, вероятно, побежали. Нет необходимости ждать 3 секунды – slezica

+0

Да, это альтернативы. – Codesingh

+0

@Codesingh Спасибо за ответ. Не могли бы вы представить полный пример? Кроме того, как насчет первого блока 'it', возвращающего 0? Как мне это сделать? –