wrapper.instance() 和 wrapper.find(Component).instance() 返回 null
wrapper.instance() and wrapper.find(Component).instance() are returning null
考虑下面的代码。
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<ComponentPage/>
</BrowserRouter>
</Provider>,
);
wrapper.instance() // null
wrapper.find(ComponentPage).instance() //null ('ComponentPage') or (<ComponentPage/>) //null
wrapper.children().first().children().first().children().first().instance() //null
然而 wrapper.name() // Provider
和 wrapper.find(ComponentPage).name() //ComponentPage
如何获取实例来测试下面的代码。
test.only('test 1', () => {
const app = wrapper.render().find(ComponentPage);
app.instance().getComponents = jest.fn(); //instance null
expect(app.instance().getComponents).toHaveBeenCalled();
});
来自 .instance() => ReactComponent 文档:
Returns the single-node wrapper's node's underlying class instance; this in its methods. It must be a single-node wrapper.
NOTE: With React 16 and above, instance() returns null for stateless functional components.
例如
index.tsx
:
import React from 'react';
export function FunctionComponent() {
return <div>function component</div>;
}
export class ClassComponent extends React.Component {
render() {
return <div>class component</div>;
}
}
index.test.tsx
:
import { mount } from 'enzyme';
import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { createStore } from 'redux';
import { ClassComponent, FunctionComponent } from '.';
const store = createStore(() => {});
describe('71204270', () => {
test('instance is null for function component', () => {
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<FunctionComponent />
</BrowserRouter>
</Provider>
);
console.log(wrapper.find(FunctionComponent).instance());
});
test('instance is class instance ', () => {
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<ClassComponent />
</BrowserRouter>
</Provider>
);
console.log(wrapper.find(ClassComponent).instance());
});
});
测试结果:
PASS Whosebug/71204270/index.test.tsx (10.179 s)
71204270
✓ instance is null for function component (49 ms)
✓ instance is class instance (9 ms)
console.log
null
at Object.<anonymous> (Whosebug/71204270/index.test.tsx:20:13)
console.log
<ref *1> ClassComponent {
props: {},
context: {},
refs: {},
updater: {
isMounted: [Function: isMounted],
enqueueSetState: [Function: enqueueSetState],
enqueueReplaceState: [Function: enqueueReplaceState],
enqueueForceUpdate: [Function: enqueueForceUpdate]
},
_reactInternalFiber: <ref *2> FiberNode {
tag: 1,
key: null,
elementType: [class ClassComponent extends Component],
type: [class ClassComponent extends Component],
stateNode: [Circular *1],
return: FiberNode {
tag: 10,
key: null,
elementType: [Object],
type: [Object],
stateNode: null,
return: [FiberNode],
child: [Circular *2],
sibling: null,
index: 0,
ref: null,
pendingProps: [Object],
memoizedProps: [Object],
updateQueue: null,
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 0,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 161,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: [FiberNode],
_debugNeedsRemount: false,
_debugHookTypes: null
},
child: FiberNode {
tag: 5,
key: null,
elementType: 'div',
type: 'div',
stateNode: [HTMLDivElement],
return: [Circular *2],
child: null,
sibling: null,
index: 0,
ref: null,
pendingProps: [Object],
memoizedProps: [Object],
updateQueue: null,
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 0,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 165,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: [Circular *2],
_debugNeedsRemount: false,
_debugHookTypes: null
},
sibling: null,
index: 0,
ref: null,
pendingProps: {},
memoizedProps: {},
updateQueue: {
baseState: null,
baseQueue: null,
shared: [Object],
effects: null
},
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 1,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 163,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: null,
_debugNeedsRemount: false,
_debugHookTypes: null
},
_reactInternalInstance: {},
state: null
}
at Object.<anonymous> (Whosebug/71204270/index.test.tsx:32:13)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 10.634 s, estimated 12 s
考虑下面的代码。
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<ComponentPage/>
</BrowserRouter>
</Provider>,
);
wrapper.instance() // null
wrapper.find(ComponentPage).instance() //null ('ComponentPage') or (<ComponentPage/>) //null
wrapper.children().first().children().first().children().first().instance() //null
然而 wrapper.name() // Provider
和 wrapper.find(ComponentPage).name() //ComponentPage
如何获取实例来测试下面的代码。
test.only('test 1', () => {
const app = wrapper.render().find(ComponentPage);
app.instance().getComponents = jest.fn(); //instance null
expect(app.instance().getComponents).toHaveBeenCalled();
});
来自 .instance() => ReactComponent 文档:
Returns the single-node wrapper's node's underlying class instance; this in its methods. It must be a single-node wrapper.
NOTE: With React 16 and above, instance() returns null for stateless functional components.
例如
index.tsx
:
import React from 'react';
export function FunctionComponent() {
return <div>function component</div>;
}
export class ClassComponent extends React.Component {
render() {
return <div>class component</div>;
}
}
index.test.tsx
:
import { mount } from 'enzyme';
import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { createStore } from 'redux';
import { ClassComponent, FunctionComponent } from '.';
const store = createStore(() => {});
describe('71204270', () => {
test('instance is null for function component', () => {
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<FunctionComponent />
</BrowserRouter>
</Provider>
);
console.log(wrapper.find(FunctionComponent).instance());
});
test('instance is class instance ', () => {
const wrapper = mount(
<Provider store={store}>
<BrowserRouter>
<ClassComponent />
</BrowserRouter>
</Provider>
);
console.log(wrapper.find(ClassComponent).instance());
});
});
测试结果:
PASS Whosebug/71204270/index.test.tsx (10.179 s)
71204270
✓ instance is null for function component (49 ms)
✓ instance is class instance (9 ms)
console.log
null
at Object.<anonymous> (Whosebug/71204270/index.test.tsx:20:13)
console.log
<ref *1> ClassComponent {
props: {},
context: {},
refs: {},
updater: {
isMounted: [Function: isMounted],
enqueueSetState: [Function: enqueueSetState],
enqueueReplaceState: [Function: enqueueReplaceState],
enqueueForceUpdate: [Function: enqueueForceUpdate]
},
_reactInternalFiber: <ref *2> FiberNode {
tag: 1,
key: null,
elementType: [class ClassComponent extends Component],
type: [class ClassComponent extends Component],
stateNode: [Circular *1],
return: FiberNode {
tag: 10,
key: null,
elementType: [Object],
type: [Object],
stateNode: null,
return: [FiberNode],
child: [Circular *2],
sibling: null,
index: 0,
ref: null,
pendingProps: [Object],
memoizedProps: [Object],
updateQueue: null,
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 0,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 161,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: [FiberNode],
_debugNeedsRemount: false,
_debugHookTypes: null
},
child: FiberNode {
tag: 5,
key: null,
elementType: 'div',
type: 'div',
stateNode: [HTMLDivElement],
return: [Circular *2],
child: null,
sibling: null,
index: 0,
ref: null,
pendingProps: [Object],
memoizedProps: [Object],
updateQueue: null,
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 0,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 165,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: [Circular *2],
_debugNeedsRemount: false,
_debugHookTypes: null
},
sibling: null,
index: 0,
ref: null,
pendingProps: {},
memoizedProps: {},
updateQueue: {
baseState: null,
baseQueue: null,
shared: [Object],
effects: null
},
memoizedState: null,
dependencies: null,
mode: 0,
effectTag: 1,
nextEffect: null,
firstEffect: null,
lastEffect: null,
expirationTime: 0,
childExpirationTime: 0,
alternate: null,
actualDuration: 0,
actualStartTime: -1,
selfBaseDuration: 0,
treeBaseDuration: 0,
_debugID: 163,
_debugIsCurrentlyTiming: false,
_debugSource: null,
_debugOwner: null,
_debugNeedsRemount: false,
_debugHookTypes: null
},
_reactInternalInstance: {},
state: null
}
at Object.<anonymous> (Whosebug/71204270/index.test.tsx:32:13)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 10.634 s, estimated 12 s