React Context API允许我将应用程序状态的逻辑放在一个位置(并避免redux)。现在看起来像这样
// Using the Context API used in react 16.3 - https://www.youtube.com/watch?v=XLJN4JfniH4
const { Provider, Consumer: ContextConsumer } = React.createContext()
class ContextProvider extends Component {
...// lot of functions ...
render() {
return (
<Provider
value={{
...this.state,
getDose: this.getDose,
getDoseRange: this.getDoseRange,
setDose: this.setDose,
checkIN: this.checkIN,
checkOUT: this.checkOUT,
getFalsifiedDrug: this.getDefaultproductData,
updatePrescriptionDose: this.updatePrescriptionDose,
}}
>
{this.props.children}
</Provider>
)
}
}
module.exports = { ContextConsumer, ContextProvider }
可以找到整个代码here。
建立开玩笑的测试以使我能够测试功能而不弄乱状态的最佳实践是什么?
(自AirBnB officially gave up using React Native起,要避免使用酶(由AirBnB开发)
如何进行测试以确认当我呼叫setDose(2)
时productData.dose
已从"5 mg"
更改为现在等于"2 mg
。但是然后将状态设置回"5 mg"
进行其他测试。
让jest
和我一起工作时遇到了一些麻烦(因此我可以尝试建议的解决方案)
package.json
{
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"test": "jest --watchAll"
},
"dependencies": {
"@expo/samples": "2.1.1",
"crypto-js": "^3.1.9-1",
"date-fns": "^1.29.0",
"expo": "^28.0.0",
"invert-color": "^1.2.3",
"lodash": "^4.17.10",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
"react-native-qrcode": "^0.2.6",
"react-native-slider": "^0.11.0",
"react-native-switch": "^1.5.0",
"react-navigation": "2.3.1",
"whatwg-fetch": "^2.0.4"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"babel-preset-expo": "^5.0.0",
"eslint": "^5.16.0",
"eslint-config-codingitwrong": "^0.1.4",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-jest": "^22.5.1",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.13.0",
"jest-expo": "^32.0.0",
"react-native-testing-library": "^1.7.0",
"react-test-renderer": "^16.8.6"
},
"jest": {
"preset": "jest-expo"
}
}
它只是把这个扔给我
> @ test /Users/norfeldt/Desktop/React-Native/MedBlockChain
> jest --watchAll
● Validation Error:
Module react-native/jest/hasteImpl.js in the haste.hasteImplModulePath option was not found.
<rootDir> is: /Users/norfeldt/Desktop/React-Native/MedBlockChain
Configuration Documentation:
https://jestjs.io/docs/configuration.html
npm ERR! Test failed. See above for more details.
我尝试过类似的事情
rm -rf node_modules/ yarn.lock package-lock.json && npm install
答案 0 :(得分:1)
您可以使用项目规范中已经使用的react-test-renderer。
您需要调用testRenderer.getInstance()
=>检查当前state
=>调用一些您需要测试的方法=>检查更新的state
:
import React from "react";
import { create } from "react-test-renderer";
import { ContextProvider } from "../Context";
describe("ContextProvider", () => {
test("it updates dose correctly", () => {
const component = create(<ContextProvider />);
const instance = component.getInstance();
expect(instance.getDose()).toBe(5);
expect(instance.state.productData.dose).toBe("5 mg");
instance.setDose(2);
expect(instance.getDose()).toBe(2);
expect(instance.state.productData.dose).toBe("2 mg");
});
test("it updates something else correctly", () => {
// ...
});
});
其他测试的状态不会受到影响。
与回购交易一起使用时,我唯一需要做的就是npm install whatwg-fetch@2.0.4 --save
,如here所述。希望这会有所帮助。
更新
即使这应该是另一个问题,显而易见的解决方案是创建一个新的rn项目并在其中复制代码,但这是我为解决代码上的jest
错误而所做的工作:
1)使版本匹配(如评论中所述...):
"expo": "^32.0.0",
"jest-expo": "^32.0.0",
// and maybe even
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
2)修复错误
api.caller不是函数
按照here的说明使用babel.config.js
:
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
env: {
development: {
plugins: ["transform-react-jsx-source"]
}
}
};
};
3)由于this
而使用yarn
答案 1 :(得分:0)
如果您正在寻找酶的替代品,我认为您应该在这里寻找:https://callstack.github.io/react-native-testing-library/
该库将允许您使用提供的update函数来更改要测试的值,然后将其改回来。
伟大的React Native库-the getting started page says it all。如果您对一些有助于您入门的代码感兴趣,那么我也可以做一些工作。
答案 2 :(得分:0)
我建议您仅对逻辑进行单元测试,并在这种情况下考虑完全避免组件测试。
您可以将方法提取到“ Presenter”中以处理数据,并且仅测试此逻辑。通过这种方法,可以轻松测试具有纯输入/输出逻辑的演示者。
例如,主持人可以看起来像这样:
// DosePresenter.js
const processDose = (value, productData) => {
productData.dose = value.toFixed(0) + productData.dose.replace(/[\d\.]*/g, '')
productData.productionTime = Conventions.datetimeStr();
productData.hashSalt = this.makeHashSalt();
return {productData, productDataHash: getHashOfproductData(productData)};
};
module.exports = {
processDose
};
用法:
// Context.js
import * as DosePresenter from './DosePresenter';
const setDose = (value) => this.setState(DosePresenter.processDose(value, {...this.state}));
现在应该更容易测试逻辑:
// DosePresenter.test.js
describe('DosePresenter tests', () => {
let uut;
beforeEach(() => {
uut = require('./DosePresenter');
});
it('should process a dose', () => {
const value = 10;
const productData = {};
expect(uut.processDose(value, productData)).toEqual(...);
});
};