Как мне выполнить тестирование компонентов, если моему компоненту требуется доступ к базе данных

#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