![](/img/trans.png)
[英]React EsLint - Component should be written as pure function and after changed it to pure function can't read the property anymore
[英]How should a pure function read a config file or open a database?
通常我的函数需要来自配置文件或数据库的数据。 我希望尽可能地使用纯函数和可以进行单元测试的东西。
我不知道如何正确地做到这一点,因为我没有 CS 学位。 我可以看到的选项是:
示例 1:
function myFunc(p1, p2, db, configFile) { ... }
但这意味着调用myFunc()
的所有其他函数也需要具有db, configFile
作为 arguments。
示例 2:
function myFunc(p1, p2) {
const config = readConfig();
dbConn = openDb();
...
}
我想这使单元测试变得不可能?
示例 3:
const struct = {
config: readConfig(),
dbConn: openDb(),
...
};
function myFunc(p1, p2, struct) { ... }
这有不利的一面,当其他函数数据也存储在这个全局struct
中时,每个 function 可以访问超出他们需要的内容。
问题
还有其他可能性吗? 推荐的方法是什么?
像这样定义myFunc()
以保持其纯净:
function myFunc(p1, p2, readConfig, openDb) { ... }
并在封闭的 scope 中调用它
// other code here
{
const config = readConfig();
const dbConn = openDb();
myFunc(p1, p2, readConfig, openDb);
}
// other code here
// config and dbConn isn't available here
一个 PoC:
function func(a, b) { console.log(a); console.log(b); } const a = undefined; const b = undefined; { const a = 'private1'; const b = 'private2'; func(a, b); } console.log(a); console.log(b);
我认为您可以在这里使用依赖注入。 像这样的东西:
function readConfig() {
// returns real config
}
function openDb() {
// return real db connection
}
function readConfigMock() {
// returns mock config
}
function openDbMock() {
// return mock db connection
}
function myFuncBuilder(readConfigFn, openDbFn) {
return function(p1, p2) {
// can use readConfigFn everywhere because of closure
const config = readConfigFn();
dbConn = openDbFn();
...
}
}
const myFunc = myFuncBuilder(readConfig, openDb);
// no need to know about openDb and readConfig
function topFunc() {
myFunc(p1, p2);
}
// code
const myFunc = myFuncBuilder(readConfig, openDb);
// test
const myFunc = myFuncBuilder(readConfigMock, openDbMock);
诀窍是将 function 作为参数传递。 此外,还有称为myFuncBuilder
的高阶 function(返回函数的函数)。 此 function 基于 2 个 arguments 构建myFunc
- 用于 db 连接的 function 和用于 Cconfig 的 ZC1C42145268E68A9F14D
因此,您可以轻松地创建readConfig
和openDb
的模拟以进行测试。
PS 此外,函数式编程范式教我们在这种情况下使用 IO 单子。 但是在 JS/TS 中使用 monad 的学习曲线非常陡峭。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.