如何测试React可加载组件

时间:2018-05-04 13:58:37

标签: reactjs unit-testing jestjs enzyme react-loadable

我有这个组件:

import React from 'react';

const UploadAsync = Loadable({
  loader: () => import('components/Upload'),
  loading: () => <LoadingComponent full />
});

const Component = () => {
  return <UploadAsync />
}

export default Component

测试:

import React from 'react';
import Component from './index';

describe('Component', () => {
  it('should render correctly with upload component', () => {
    const tree = create(<Component />).toJSON();

    expect(tree).toMatchSnapshot();
  });
});

如何在快照中看到上传组件而不是加载组件?

exports[`Content should render correctly with form component 1`] = `
  <div>
    <Loading
      full={true}
    />
  </div>
`;

到目前为止,我已尝试setTimeOutPromises

6 个答案:

答案 0 :(得分:3)

我也无法弄清楚这一点,但是,有一些变通办法,无论单独还是一起,都可能会很好地起作用:

快照测试传递给Loadable的组件

对于您来说,测试看起来像这样:

import React from 'react';
import Component from './components/Upload';

describe('Component', () => {
  it('should render correctly with upload component', () => {
    const tree = create(<Component />).toJSON();

    expect(tree).toMatchSnapshot();
  });
});

您也可以用类似的方式测试<LoadingComponent full />。不,这不能保证您Loadable组件正常工作,但是您可以 满意地假设react-loadable库已经过良好测试并且可以正常工作当您传递给您自己的,经过正确测试的组件时。

端到端浏览器测试

使用SeleniumTestCafe之类的框架,您可以编写在实际浏览器中运行的针对您网站的测试。

答案 1 :(得分:1)

我正在尝试测试其中具有Loadable-components的组件,并遇到类似的问题。我设法模拟了这些组件,并按我的意愿安装了父组件(酶)。

我省去了模拟商店和道具,因为它们与解决方案无关

const component = () => {
  return mount(
    <Provider store={store}>
      <DoubleMatrix {...props} />
    </Provider>
  )
}

// These are the Loadable-components, import { Grid, GridColumn } from 'App/Components/Tables/Grid' in the parent component which I am testing

jest.mock('App/Components/Tables/Grid', () => ({
  Grid: () => <div />, // eslint-disable-line
  GridColumn: () => <div />, // eslint-disable-line
}))

it('renders', () => {
  const wrapper = component()
  expect(wrapper).toMatchSnapshot()
})

答案 2 :(得分:0)

似乎没有合适的解决方案,但如果您的测试实际上是在iframe中的浏览器中渲染组件,那么您可以通过Jquery contentDocument获取您的反应组件

$('#component-iframe')[0].contentDocument

您可以使用

按类或ID查找组件中的某些特定元素
$('#component-iframe')[0].contentDocument.getElementById('componentID')

答案 3 :(得分:0)

我有一个偶然发现的解决方案,但我不知道它是如何工作的(也许我们可以找出解决办法,也许可以解决这个问题)。目前,这是一种解决方法。

如果您在测试外调用一次mount,动态模块将神奇地加载:

function mountApp() {
  return mount(
    <ApolloProvider client={apolloClient}>
      <MemoryRouter initialEntries={['/']}>
        <App />
      </MemoryRouter>
    </ApolloProvider>
  );
}

mountApp();

// Tests
test('react-loadable module loads', () => {
  const wrapper = mountApp();
  console.log(wrapper.debug());
});

此处,包含App个模块的react-loadable已正确加载,其所有内容均可用。当我删除第一个mountApp时,它不再起作用(它仅加载加载字符串)。

编辑: 实际上,它也可以在测试中使用,但是通过这种方式,您只需为每个测试运行一次即可。

答案 4 :(得分:0)

以下是测试加载的组件的方法:

import {LoadableFoo} from './loadable-foo';
import {Foo} from './Foo';

it('should load the Foo component', async () => {
  // usual shallow render
  const component = shallow(<Loadable/>);  

  // prerender the Loadable component
  const loadedComponent = await component.preload();

  expect(loadedComponent.Foo).toEqual(Foo);
});

答案 5 :(得分:0)

在测试之前使用Loadable.preloadAll(),然后就可以访问所需的组件。

Docs

简单的例子:

all imports here

Loadable.preloadAll()

describe('TestName', () => {
 //tests
})