我的Jest测试失败,因为每次测试运行时密钥的时间戳都不同:
FAIL ./App.test.js
✕ renders without crashing (72ms)
● renders without crashing
expect(value).toMatchSnapshot()
Received value does not match stored snapshot 1.
- Snapshot
+ Received
@@ -347,11 +347,11 @@
"index": 0,
"isTransitioning": false,
"key": "StackRouterRoot",
"routes": Array [
Object {
- "key": "id-1519567169760-0",
+ "key": "id-1519567814666-0",
"routeName": "Menu",
},
],
},
}
这是我的App.js文件:
import React from 'react';
import { StackNavigator } from 'react-navigation';
import Menu from './components/Menu';
import List from './components/List';
const RootStack = StackNavigator(
{
Menu: {
screen: Menu,
},
List: {
screen: List,
},
},
{
initialRouteName: 'Menu',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
这是我的测试文件:
import React from 'react';
import App from './App';
import renderer from 'react-test-renderer';
test('renders without crashing', () => {
const rendered = renderer.create(<App />).toJSON();
expect(rendered).toBeTruthy();
expect(rendered).toMatchSnapshot();
});
是否可以覆盖键值,或者在测试运行时是否有办法忽略键?
答案 0 :(得分:2)
您可以模拟不确定的数据。 https://facebook.github.io/jest/docs/en/snapshot-testing.html#tests-should-be-deterministic
例如,如果你有一个使用Date.now()的Clock组件,那么 从此组件生成的快照每次都会有所不同 测试用例运行。在这种情况下,我们可以模拟Date.now()方法 每次运行测试时返回一致的值:
Date.now = jest.fn(()=&gt; 1482363367071);
现在,每次快照测试用例运行时,Date.now()都会返回 始终是1482363367071。这将产生相同的快照 无论何时运行测试,都会为此组件生成。
答案 1 :(得分:2)
您可以在jest设置文件中使用模拟函数覆盖键值: https://facebook.github.io/jest/docs/en/configuration.html#setupfiles-array
通过将Date.now模拟为Date.now = jest.fn(() => 123)
来将密钥设置为始终相同,因为引擎反应导航使用此方法生成路由密钥:https://github.com/react-navigation/react-navigation/blob/master/src/routers/KeyGenerator.js
答案 2 :(得分:2)
较新版本的jest还支持property matchers,该{{3}}允许使用匹配器来评估快照的某些部分,而不是要求整个快照都相同。
以下是文档中的示例:
it('will check the matchers and pass', () => {
const user = {
createdAt: new Date(),
id: Math.floor(Math.random() * 20),
name: 'LeBron James',
};
expect(user).toMatchSnapshot({
createdAt: expect.any(Date),
id: expect.any(Number),
});
});
// Snapshot
exports[`will check the matchers and pass 1`] = `
Object {
"createdAt": Any<Date>,
"id": Any<Number>,
"name": "LeBron James",
}
`;
答案 3 :(得分:1)
我找到了完全不同的解决方案,作为对自己类似问题的回答。
我解决了我的问题,但没有通过嘲笑Date.now来解决。
相反,我改编了一个名为 joeybaker 的用户在https://github.com/react-navigation/react-navigation/issues/2269#issuecomment-369318490上找到的答案。
其理由如下:
对于您的测试目的,键并不是很重要。你什么 真正关心的是路线和索引。
他的代码如下,并假定在 Redux 中使用动作和缩减器:
// keys are date and order-of-test based, so just removed them
const filterKeys = (state) => {
if (state.routes) {
return {
...state,
routes: state.routes.map((route) => {
const { key, ...others } = route
return filterKeys(others)
}),
}
}
return state
}
it('clears all other routes', () => {
const inputState = {}
const action = { type: AUTH_LOGOUT_SUCCESS }
const state = filterKeys(reducer(inputState, action))
expect(state.routes).toBe........
})
我已针对我的情况进行了以下调整(我尚未使用 Redux ):
test("renders correctly", () => {
const tree = renderer.create(<StackNavigator />);
const instance = tree.getInstance();
const state = filterKeys(instance.state.nav);
expect(state).toMatchSnapshot();
});
// keys are date and order-of-test based, so just removed them
const filterKeys = (state) => {
if (state.routes) {
return {
...state,
routes: state.routes.map((route) => {
const { key, ...others } = route
return filterKeys(others);
}),
}
}
return state;
};
呈现的测试如下:
// Jest Snapshot v1
exports[`renders correctly 1`] = `
Object {
"index": 0,
"isTransitioning": false,
"key": "StackRouterRoot",
"routes": Array [
Object {
"index": 0,
"isTransitioning": false,
"routeName": "FluidTransitionNavigator",
"routes": Array [
Object {
"routeName": "SignInOrRegister",
},
],
},
],
}
`;