如何使用服务测试React组件?

时间:2019-03-15 06:26:38

标签: javascript reactjs

考虑具有服务(REST或持久性等)的组件,如何初始化服务的一种方法是在组件构造函数中:

import {Component} from 'react';
import MyRestService from '../service/MyRestService';

class MyComponent extends Component {
    constructor(props) {
        super(props);

        this.service = new MyService('http://www.example.com');
    ...

另一种方法是将其初始化为全局常量:

import {Component} from 'react';
import MyRestService from '../service/MyRestService';

const service = new MyService('http://www.example.com');

class MyComponent extends Component {
    ...

这两种方法都是静态的,不需要跟随我动态地初始化服务,因此很难对其进行测试。

在测试中,我想在组件上模拟操作时将模拟服务注入组件并验证对服务的调用。

为可通过模拟测试的React组件创建服务的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

您可以使用testdouble.js替换/模拟依赖项。 您可以在测试文件中执行类似的操作

// replacing the dependency so that when the dependency is called
// in other file, it will get the mocked one instead.
const MyRestService = td.replace('../service/MyRestService');

// replace its behaviour
td.when(MyService('http://www.example.com')).thenReturn(something)

// validate that myservice has been called with particular argument
td.verify(MyService('http://www.example.com'))

答案 1 :(得分:0)

出于测试目的,您应该提供2个测试套件:一个单独用于服务(作为单元测试),另一个用于组件作为集成测试。验证对您服务的服务调用将在单元测试中进行测试,而组件操作将在集成测试中进行测试。

对于实现而言,使服务启动更加动态化的一种方法是将服务参数作为道具或组件状态传递:

class MyComponent extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        initService();
    }

    componentDidUpdate(prepProps, prepState) {
        if (prepProps.serviceParams !== this.props.serviceParams) {
            initService();
        }
    }

    componentWillUnmount() {
        // stop whatever your service is doing here
        delete this.service;
    }

    initService() {
        if (!!this.props.serviceParams) {
            if (!!this.service) {
                // stop your current service
            }
            this.service = new MyService(this.props.serviceParams);
        }
    }

    ...
}