#reactjs #electron #jestjs #enzyme
#reactjs #electron #jestjs #фермент
Вопрос:
Я создал приложение electron, которое сохраняет данные в NeDB, которое отображает данные через приложение. Я пытаюсь протестировать свой компонент, который отображает данные с помощью jest и enzyme, но мой простой тест завершается неудачей, потому что один из моих модулей, импортируемых в файл, требует доступа к свойству, которое определяется только при запуске приложения electron.
Я новичок в создании приложения electron, поэтому моя архитектура может быть плохой.
Основная проблема заключается в том, что при попытке запустить свой тест я получаю сообщение об ошибке,
TypeError: Cannot read property 'app' of undefined
1 | const remote = require('electron').remote;
> 2 | const app = remote.app;
Как мне это исправить? Некоторые возможные вещи, которые, как я думал, могли бы сработать, — это использовать jest для издевательства над SchoolAPI, но я не уверен, как это сделать.
SchoolList.js
import React from "react";
// @material-ui/core components
import withStyles from "@material-ui/core/styles/withStyles";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import IconButton from '@material-ui/core/IconButton';
import DeleteIcon from '@material-ui/icons/Delete';
import { Link } from "react-router-dom";
import * as SchoolAPI from "../../utils/SchoolAPI.js"
class SchoolList extends React.Component {
constructor(props) {
super(props);
};
handleDelete = (id) => {
SchoolAPI.deleteSchool(id).then(() => {
this.props.onLoadData();
});
};
render() {
const { classes } = this.props;
const listSchools = this.props.schoolsData.map((school, i) =>
<div key={i}>
<ListItem button component={Link} to={`/orders/${i}`}>
<ListItemText primary={school.name}/>
<ListItemSecondaryAction onClick={() => this.handleDelete(school["_id"])}>
<IconButton aria-label="Delete" >
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</div>
);
return (
<List className="schoolList">
{listSchools}
</List>
);
};
}
SchoolAPI.js
import db from "../db.js"
...a bunch of API(e.g. db.insert(..))
db.js
const remote = require('electron').remote;
const app = remote.app;
const path = require('path');
const Datastore = require('nedb-promises');
const dbFactory = (fileName) => Datastore.create({
filename: `${process.env.NODE_ENV === 'dev' ? '.' : app.getPath('userData')}/data/${fileName}`,
timestampData: true,
autoload: true
});
const db = {
schools: dbFactory('schools.db')
};
module.exports = db;
test.spec.js
describe("SchoolList component", () => {
it("renders without throwing an error", () => {
const SchoolListComponent = renderer.create(<SchoolList schoolsData={schoolsData/>).toJson();
expect(SchoolListComponent).toMatchSnapshot();
});
});
Комментарии:
1. Вы нашли решение?
Ответ №1:
Вы действительно должны издеваться над SchoolAPI, поскольку ваш компонент требует SchoolAPI только при его удалении, что не должно слишком сильно влиять на ваш компонент. Школьные данные, которые вы можете просто смоделировать и передать в компонент, если это необходимо. Итак, это будет выглядеть следующим образом:
jest.mock('./path/to/SchoolAPI');
describe("SchoolList component", () => {
it("renders without throwing an error", () => {
const SchoolListComponent = renderer.create(<SchoolList schoolsData={schoolsData/>).toJson();
expect(SchoolListComponent).toMatchSnapshot();
});
});
Если вы хотите иметь макеты, которые ведут себя аналогично исходным реализациям, а не просто ничего не возвращают, вы можете заглянуть в jest manual mocks