Я пытаюсь протестировать вызов метода компонента из элемента React Native Button.
По какой-то причине тест не проходит, если я не сделаю ОБА из этих вещей.
wrapper.find(Button).first().props().onPress();
wrapper.find(Button).first().simulate('press');
Если я закомментирую одну из строк, тест не пройдет, что означает сбой expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();.
Вот моя составляющая:
import React, { Component } from 'react';
import { Button, SafeAreaView, Text } from 'react-native';
import EmailPasswordModal from './EmailPasswordModal/EmailPasswordModal';
class Login extends Component {
state = {
emailPasswordModalVisible: false,
};
toggleEmailPasswordModal = () => {
console.info('TOGGLED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
const { emailPasswordModalVisible } = this.state;
this.setState({ emailPasswordModalVisible: !emailPasswordModalVisible });
};
render() {
const { emailPasswordModalVisible } = this.state;
return (
<SafeAreaView>
<EmailPasswordModal
visible = { emailPasswordModalVisible }
close = { this.toggleEmailPasswordModal }
/>
<Text>Login Screen!</Text>
<Button
onPress = { this.toggleEmailPasswordModal }
title = "Login with Email and Password"
color = "#841584"
accessibilityLabel = "Login with Email and Password"
/>
</SafeAreaView>
);
}
}
export default Login;
Вот мой тест:
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import { shallow } from 'enzyme';
import { Button } from 'react-native';
import Login from './Login';
describe('Login Screen', () => {
describe('Snapshot Tests', () => {
it('renders the screen with default state', () => {
const renderer = new ShallowRenderer();
const props = {};
renderer.render(<Login { ...props } />);
expect(renderer.getRenderOutput()).toMatchSnapshot();
});
});
describe('Functional Tests', () => {
it('calls the toggleEmailPasswordModal method', () => {
const wrapper = shallow(<Login />);
const instance = wrapper.instance();
jest.spyOn(instance, 'toggleEmailPasswordModal');
wrapper.find(Button).first().props().onPress();
wrapper.find(Button).first().simulate('press');
expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();
});
});
});
Как ни странно, когда тест запускается, в выходных данных отображается «TOGGLED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!! " дважды из-за входа в компонент.
Однако, если я поменяю expect на:
expect(instance.toggleEmailPasswordModal).toHaveBeenCalledTimes(1);
тест проходит.
Если я поменяю expect на:
expect(instance.toggleEmailPasswordModal).toHaveBeenCalledTimes(2);
тест не проходит, говорят, что toggleEmailPasswordModal вызывали только 1 раз.
Зачем мне нужны ОБЕИХ из этих линий wrapper.find(Button)...? Я никогда не видел других тестов, требующих их обоих.
Спасибо, Джастин
Я обновил свой тест следующим образом:
it('calls the toggleEmailPasswordModal method', () => {
const wrapper = shallow(<Login />);
const instance = wrapper.instance();
jest.spyOn(instance, 'toggleEmailPasswordModal');
wrapper.find(Button).first().props().onPress();
wrapper.find(Button).first().simulate('press');
expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();
// I ADDED THIS SECTION HERE
expect(instance.state.emailPasswordModalVisible).toBe(true);
});
Тест не проходит, потому что instance.state.emailPasswordModalVisible = false. Это странно, поскольку, по-видимому, называется toggleEmailPasswordModal. Однако, поскольку я подозреваю, что на самом деле он вызывается дважды, я обновляю тест следующим образом:
it('calls the toggleEmailPasswordModal method', () => {
const wrapper = shallow(<Login />);
const instance = wrapper.instance();
jest.spyOn(instance, 'toggleEmailPasswordModal');
wrapper.find(Button).first().props().onPress();
// CHANGES START HERE
// wrapper.find(Button).first().simulate('press');
// expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();
expect(instance.state.emailPasswordModalVisible).toBe(true);
});
Угадай, что? Тест проходит нормально. Таким образом, ЯВНО, дважды вызывая функции wrapper.find..., на самом деле дважды вызывает метод toggleEmailPasswordModal. Итак, почему он не может его обнаружить, если я не звоню дважды? Почему он ошибочно полагает, что метод был вызван только один раз?





Наконец-то у меня есть ответ. Согласно Вызывается функция Jest spyOn, мне нужно сделать instance.forceUpdate(), чтобы прикрепить шпион к компоненту.
it('calls the toggleEmailPasswordModal method', () => {
const wrapper = shallow(<Login />);
const instance = wrapper.instance();
const spy = jest.spyOn(instance, 'toggleEmailPasswordModal');
// This is added per https://stackoverflow.com/questions/44769404/jest-spyon-function-called/44778519#44778519
instance.forceUpdate();
wrapper.find(Button).first().props().onPress();
expect(spy).toHaveBeenCalledTimes(1);
expect(instance.state.emailPasswordModalVisible).toBe(true);
});
Теперь тест пройден!