如何使用 React apollo 组件进行单元测试?
How make unit test with react apollo component?
我想用 mocha、jsdom chai 和 enzyme 做单元测试。
我已经做了一些单元测试,它们运行良好。
但是,连接到 apollo 商店的组件不起作用...我有一个错误。
这是一个测试,组件连接到 apollo store:
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import ReviewList from '../../src/components/tibco/review-list/review-list';
import NewReview from '../../src/components/tibco/review-list/new-review';
const data = {
loading: false,
allCodeReviews: {
edges: {
node: {
id: "Q29kZVJldmlld05vZGU6MQ==",
reference: 4545,
reviewer: "John",
revisionDate: "2016-11-25",
redmineUrl: "http://url.4545.com",
flow: {
id: "Rmxvd05vZGU6MQ==",
name: "foo"
}
}
}
},
allUsers: {
edges: {
node: {
username: "John"
}
}
},
allFlows: {
edges: {
node: {
name: "Foo",
id: "Rmxvd05vZGU6MQ=="
}
}
}
};
var selectRowProp = {
mode: "checkbox",
clickToSelect: true,
bgColor: "rgb(238, 193, 213)"
};
describe('<ReviewList />', () => {
it('Foo test...', () => {
const wrapper = shallow(
<ReviewList data={data} selectRowProp={selectRowProp}/>
);
});
});
这是组件 ReviewList:
const ReviewList = graphql(allCodeReviews)(React.createClass({
propTypes: {
data: PropTypes.shape({
loading: PropTypes.bool.isRequired,
allCodeReviews: PropTypes.object,
allFlows: PropTypes.object,
allUsers: PropTypes.object
}).isRequired
},
render() {
if (this.props.data.loading == true) {
return <center>Waiting...</center>
}
return (
<div></div>
)
}
}
)
);
当我 运行 npm 测试时,我有这个 跟踪日志 :
> tibco-frontend@0.1.0 test D:\Outils dev\_projet_pycharm\tibco_react
> mocha --compilers js:babel-register tests/index.js
<ReviewList />
Warning: Failed context type: Required context `store` was not specified in `Apollo(ReviewList)`.
in Apollo(ReviewList)
Warning: Failed context type: Required context `client` was not specified in `Apollo(ReviewList)`.
in Apollo(ReviewList)
1) Foo test...
0 passing (44ms)
1 failing
1) <ReviewList /> Foo test...:
Invariant Violation: Could not find "client" in the context of "Apollo(ReviewList)". Wrap the root component in an
<ApolloProvider>
at invariant (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react-apollo\node_modules\invariant\invariant
.js:42:15)
at new GraphQL (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react-apollo\graphql.js:138:17)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactCompositeComponent.js:294:18
at measureLifeCyclePerf (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactCompositeComponent.
js:74:12)
at [object Object].ReactCompositeComponentMixin._constructComponentWithoutOwner (D:\Outils dev\_projet_pycharm\tib
co_react\node_modules\react\lib\ReactCompositeComponent.js:293:16)
at [object Object].ReactCompositeComponentMixin.mountComponent (D:\Outils dev\_projet_pycharm\tibco_react\node_mod
ules\react\lib\ReactCompositeComponent.js:187:21)
at Object.ReactReconciler.mountComponent (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactRe
conciler.js:47:35)
at [object Object].ReactShallowRenderer._render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\
ReactTestUtils.js:402:21)
at _batchedRender (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactTestUtils.js:383:12)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\r
eact\lib\Transaction.js:138:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\reac
t\lib\ReactDefaultBatchingStrategy.js:63:19)
at Object.batchedUpdates (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactUpdates.js:98:20)
at [object Object].ReactShallowRenderer.render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\R
eactTestUtils.js:376:16)
at [object Object].render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\react-compat.js:146
:39)
at new ShallowWrapper (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\ShallowWrapper.js:81:21
)
at shallow (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\shallow.js:21:10)
at Context.<anonymous> (review-list.spec.js:52:21)
at callFn (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runnable.js:315:21)
at Test.Runnable.run (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runnable.js:308:7)
at Runner.runTest (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:422:10)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:533:12
at next (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:342:14)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:352:7
at next (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:284:14)
at Immediate._onImmediate (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:320:5)
npm ERR! Test failed. See above for more details.
有没有办法为了单元测试而断开这个组件?
首先,您可以在 Apollo 的 graphql()
HOC 中将组件的定义与其包装分开。然后,您可以继续 export default
Apollo 化组件,但您可以 export
裸组件作为命名导出:
export const ReviewList = React.createClass({
// ...
});
export default graphql(allCodeReviews)(ReviewList);
...在您希望通过 Apollo 连接的普通代码中,您将继续像这样导入默认值:
import ReviewList from 'components/tibco/review-list/review-list';
...但是在您的单元测试代码中,您使用了这样的命名导入:
import { ReviewList } from 'components/tibco/review-list/review-list';
您应该在单元测试中将您的组件放入 "MockedProvider"。
<MockedProvider mocks={mocks} addTypename={false}>
<ReviewList/>
</MockedProvider>
此处的 mocks 数组采用具有特定 GraphQL 请求及其结果的对象。
const mocks = [
{
request: {
query: GET_ALL_CODE_REVIEWS
},
result: {
data: {
[...put your data here],
},
},
},
];
Here你可以找到更多的解释。
我想用 mocha、jsdom chai 和 enzyme 做单元测试。 我已经做了一些单元测试,它们运行良好。
但是,连接到 apollo 商店的组件不起作用...我有一个错误。
这是一个测试,组件连接到 apollo store:
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import ReviewList from '../../src/components/tibco/review-list/review-list';
import NewReview from '../../src/components/tibco/review-list/new-review';
const data = {
loading: false,
allCodeReviews: {
edges: {
node: {
id: "Q29kZVJldmlld05vZGU6MQ==",
reference: 4545,
reviewer: "John",
revisionDate: "2016-11-25",
redmineUrl: "http://url.4545.com",
flow: {
id: "Rmxvd05vZGU6MQ==",
name: "foo"
}
}
}
},
allUsers: {
edges: {
node: {
username: "John"
}
}
},
allFlows: {
edges: {
node: {
name: "Foo",
id: "Rmxvd05vZGU6MQ=="
}
}
}
};
var selectRowProp = {
mode: "checkbox",
clickToSelect: true,
bgColor: "rgb(238, 193, 213)"
};
describe('<ReviewList />', () => {
it('Foo test...', () => {
const wrapper = shallow(
<ReviewList data={data} selectRowProp={selectRowProp}/>
);
});
});
这是组件 ReviewList:
const ReviewList = graphql(allCodeReviews)(React.createClass({
propTypes: {
data: PropTypes.shape({
loading: PropTypes.bool.isRequired,
allCodeReviews: PropTypes.object,
allFlows: PropTypes.object,
allUsers: PropTypes.object
}).isRequired
},
render() {
if (this.props.data.loading == true) {
return <center>Waiting...</center>
}
return (
<div></div>
)
}
}
)
);
当我 运行 npm 测试时,我有这个 跟踪日志 :
> tibco-frontend@0.1.0 test D:\Outils dev\_projet_pycharm\tibco_react
> mocha --compilers js:babel-register tests/index.js
<ReviewList />
Warning: Failed context type: Required context `store` was not specified in `Apollo(ReviewList)`.
in Apollo(ReviewList)
Warning: Failed context type: Required context `client` was not specified in `Apollo(ReviewList)`.
in Apollo(ReviewList)
1) Foo test...
0 passing (44ms)
1 failing
1) <ReviewList /> Foo test...:
Invariant Violation: Could not find "client" in the context of "Apollo(ReviewList)". Wrap the root component in an
<ApolloProvider>
at invariant (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react-apollo\node_modules\invariant\invariant
.js:42:15)
at new GraphQL (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react-apollo\graphql.js:138:17)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactCompositeComponent.js:294:18
at measureLifeCyclePerf (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactCompositeComponent.
js:74:12)
at [object Object].ReactCompositeComponentMixin._constructComponentWithoutOwner (D:\Outils dev\_projet_pycharm\tib
co_react\node_modules\react\lib\ReactCompositeComponent.js:293:16)
at [object Object].ReactCompositeComponentMixin.mountComponent (D:\Outils dev\_projet_pycharm\tibco_react\node_mod
ules\react\lib\ReactCompositeComponent.js:187:21)
at Object.ReactReconciler.mountComponent (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactRe
conciler.js:47:35)
at [object Object].ReactShallowRenderer._render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\
ReactTestUtils.js:402:21)
at _batchedRender (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactTestUtils.js:383:12)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\r
eact\lib\Transaction.js:138:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\reac
t\lib\ReactDefaultBatchingStrategy.js:63:19)
at Object.batchedUpdates (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\ReactUpdates.js:98:20)
at [object Object].ReactShallowRenderer.render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\react\lib\R
eactTestUtils.js:376:16)
at [object Object].render (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\react-compat.js:146
:39)
at new ShallowWrapper (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\ShallowWrapper.js:81:21
)
at shallow (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\enzyme\build\shallow.js:21:10)
at Context.<anonymous> (review-list.spec.js:52:21)
at callFn (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runnable.js:315:21)
at Test.Runnable.run (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runnable.js:308:7)
at Runner.runTest (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:422:10)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:533:12
at next (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:342:14)
at D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:352:7
at next (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:284:14)
at Immediate._onImmediate (D:\Outils dev\_projet_pycharm\tibco_react\node_modules\mocha\lib\runner.js:320:5)
npm ERR! Test failed. See above for more details.
有没有办法为了单元测试而断开这个组件?
首先,您可以在 Apollo 的 graphql()
HOC 中将组件的定义与其包装分开。然后,您可以继续 export default
Apollo 化组件,但您可以 export
裸组件作为命名导出:
export const ReviewList = React.createClass({
// ...
});
export default graphql(allCodeReviews)(ReviewList);
...在您希望通过 Apollo 连接的普通代码中,您将继续像这样导入默认值:
import ReviewList from 'components/tibco/review-list/review-list';
...但是在您的单元测试代码中,您使用了这样的命名导入:
import { ReviewList } from 'components/tibco/review-list/review-list';
您应该在单元测试中将您的组件放入 "MockedProvider"。
<MockedProvider mocks={mocks} addTypename={false}>
<ReviewList/>
</MockedProvider>
此处的 mocks 数组采用具有特定 GraphQL 请求及其结果的对象。
const mocks = [
{
request: {
query: GET_ALL_CODE_REVIEWS
},
result: {
data: {
[...put your data here],
},
},
},
];
Here你可以找到更多的解释。