В React я тестирую, что нажатие кнопки внутри дочернего компонента вызывает функцию, вызываемую в родительском компоненте (onDeleteClick), через всплывающее событие.
Для этого теста я использую mount
, так как мелкий не позволит нам запускать функцию в дочернем компоненте.
onDeleteClick
, функция, которую я пытаюсь проверить, была ли она вызвана или нет, является свойством класса, которое в данном случае является функцией стрелки.
Я прикалываюсь над функцией onDeleteClick и передаю ее в свой компонент через Redux Provider
при запуске теста.
Проблема, с которой я сталкиваюсь, заключается в том, что в конце теста, когда я выполняю проверку, чтобы проверить, была ли вызвана смоделированная функция, она возвращает 0.
expect(onDeleteClick.mock.calls.length).toBe(1);
Если я поместил console.log в onDeleteClick (), он будет выведен во время теста, поэтому я знаю, что функция на самом деле вызывается.
Я немного исследовал это и до сих пор не получил ничего, чтобы работать.
Некоторые предложения заключались в том, чтобы шпионить за моей поддельной функцией, а затем вызвать forceUpdate для оболочки, но это не дало никаких положительных результатов.
Для этого я использую Jest
с Enzyme
.
Ссылочный код:
Parent.js
import { deleteAccount } from '../../actions/profileActions';
import ChildComponent from '../common/ChildComponent';
class ParentComponent extends Component {
onDeleteClick = () => {
console.log('onDeleteClick was executed during this test!')
this.props.deleteAccount();
}
render() {
let dashboardContent;
dashboardContent = (
<div>
<ChildComponent onDelete={this.onDeleteClick} />
</div>
);
return (
<div>
{dashboardContent}
</div>
);
}
}
// propTypes and mapStateToProps removed from this post
export default connect(
mapStateToProps,
{ deleteAccount }
)(ParentComponent);
__ испытания __ / ParentComponent.js
import React from 'react';
import { mount } from 'enzyme';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import ParentComponent from '../ParentComponent';
import thunk from "redux-thunk";
const mockStore = configureStore([thunk]);
const deleteAccount = jest.fn();
const props = {
deleteAccount
}
const randomTestState = {
// some initial state, not important
};
const randomTestStore = mockStore(randomTestState);
describe('<ParentComponent />', () => {
it(`mounts the ParentComponent component and, when ChildComponent sends onDelete, then deleteAccount function is called once`, () => {
const wrapper = mount(
<Provider store={randomTestStore} props={props}>
<Router >
<ParentComponent />
</Router>
</Provider>
);
// Here, I grab an element in ChildComponent and simulate a click using Enzyme, then the event bubbles up, and deleteAccount() is called in the parent component.
// the console.log we expect to see from onDeleteClick is logged to console.
// the call does not seem to have registered though and the expect returns falsy
expect(deleteAccount.mock.calls.length).toBe(1);
})
});
Может быть проблема в том, что я обертываю компонент в провайдере?
У меня есть предчувствие, но я не смог найти конкретных примеров тестов, которые используют провайдера для переноса их компонента при выполнении интеграционного тестирования