[英]Node dependency container doesn't work as expected
I have a DI container like this: 我有一个像这样的DI容器:
# di-container.js
const container = {
fileReader: require("./file-reader"),
csvReader: require("./csv-reader"),
}
module.exports = {
container
}
And csv-reader.js
looks like this: 而csv-reader.js
看起来像这样:
# csv-reader.js
const { container } = require("./di-container")
async function readFileAsCSV(path)
const fileContents = await container.fileReader.readFileContents(path)
return fileContents.split("\n")
.map(line => line.split(","))
}
I have a test file csv-reader.spec.js
: 我有一个测试文件csv-reader.spec.js
:
# csv-reader.spec.js
const { container } = require("./di-container")
describe("csvReader", () => {
it("should read cells from file", async () => {
const fakeCSV = "\"Name\",\"Age\"\n\"Bob Smith\",\"32\""
container.fileReader.readFileContents = (_) => fakeCSV
const result = container.csvReader.readFileAsCSV()
# Do some assertions...
})
})
When running the test it fails with the error (stack trace line numbers different as the example is slightly different): 运行测试时,它会因错误而失败(堆栈跟踪行号不同,因为示例略有不同):
TypeError: Cannot read property 'fileReader' of undefined
at Object.readFileAsCSV (csv-reader.js:8:42)
at Context.it (csv-reader.spec.js:15:44)
at processImmediate (internal/timers.js:443:21)
I expected that the memory reference to container
is the same in csv-reader.spec.js
and csv-reader.js
, so I should be able to change container.fileReader.readFileContents
and csv-reader
will use the mock function. 我期望在csv-reader.spec.js
和csv-reader.js
对container
的内存引用是相同的,所以我应该能够更改container.fileReader.readFileContents
和csv-reader
将使用mock函数。
If I remove the csvReader: require("./csv-reader")
line from di-container.js
and use const csvReader = require("./csv-reader")
in csv-reader.spec.js
, then the test passes. 如果我从di-container.js
删除csvReader: require("./csv-reader")
行并在csv-reader.spec.js
使用const csvReader = require("./csv-reader")
,那么测试经过。 This would suggest some oddity with the order in which the dependencies in container
are being created. 这表明在创建container
中的依赖项的顺序方面存在一些奇怪之处。
I have tried rearranging the order of fileReader
and csvReader
in container
, and changing them to be like container.fileReader = ...
instead of inline instantiation but that did not work.jav 我已经尝试重新排列container
的fileReader
和csvReader
的顺序,并将它们更改为像container.fileReader = ...
而不是内联实例化但是没有工作.jav
You have a dependency module cycle . 您有一个依赖模块循环 。
Your di-container.js
file requires csv-reader.js
and csv-reader.js
file requires di-container.js
which forms a cycle. 你的di-container.js
文件需要csv-reader.js
和csv-reader.js
文件需要di-container.js
来形成一个循环。
Because of this, require("./di-container")
returns null
inside the csv-reader.js
file. 因此, require("./di-container")
在csv-reader.js
文件中返回null
。 Because require("./di-container")
is null
, The destructured container
will be undefined. 因为require("./di-container")
为null
,所以destructured container
将是未定义的。 And thus, your are getting the error which you mentioned. 因此,你得到了你提到的错误。
You need to redesign your functions and might want to think about where do you want to put them. 您需要重新设计您的功能,并可能想要考虑您希望将它们放在何处。
On very broad level, just separate out the functions which are to be used in both the files and put them inside common.js
在非常广泛的层面上,只需将两个文件中使用的函数分开并将它们放在common.js
Then, require common.js
inside csv-reader.js
and di-container.js
然后,在csv-reader.js
和di-container.js
common.js
If I remove the csvReader: require("./csv-reader") line from di-container.js and use const csvReader = require("./csv-reader") in csv-reader.spec.js, then the test passes. 如果我从di-container.js中删除csvReader:require(“./ csv-reader”)行并在csv-reader.spec.js中使用const csvReader = require(“./ csv-reader”),那么测试经过。 This would suggest some oddity with the order in which the dependencies in container are being created. 这表明在创建容器中的依赖项的顺序方面存在一些奇怪之处。
The cycle broke once you did not require csv-reader.js
from the di-container.js
and hence it is working just fine. 一旦你不需要来自di-container.js
csv-reader.js
破坏循环,因此它工作得很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.