[英]Mocked `fs.createFileSync` and `fs.unlinkSync` are not getting called
我有一個函數可以做很多事情,但其中之一是它將文件復制到一個特殊的目錄,用它做一些事情(在不使用fs
模塊的情況下調用一些東西與該文件進行交互),然后刪除復制的文件一旦完成。
import { copyFileSync, unlinkSync } from 'fs';
myOtherFunction(path: string) {
...
}
myIOFunction(somePath: string) {
var copyPath = resolve('otherDir/file2.csv');
copyFileSync(somePath, copyPath);
try {
myOtherFunction(copyPath);
} finally {
unlinkFileSync(copyPath);
}
}
export myFunction() {
...
myIOFunction(resolve('file1.csv));
}
由於只有myFunction()
被導出(它是唯一應該能夠直接與之交互的東西),我必須通過它對myOtherFunction()
和myIOFunction()
進行單元測試。 其中一部分是copyFileSync
和unlinkFileSync
。
我的測試看起來像這樣:
import * as fs from 'fs';
import myFunction from './myFile';
...
it("tests something involving input/output", () => {
mockCopyFile = spyOn(fs, 'copyFileSync');
mockUnlinkFile = spyOn(fs, 'unlinkSync');
...
myFunction();
expect(mockCopyFile).toHaveBeenCalledWith(resolve('file1.csv'), resolve('otherDir/file2.csv'));
expect(mockUnlinkFile).toHaveBeenCalled();
...
});
試驗是用,無論是錯誤失敗mockCopyFile
也不mockUnlinkFile
被調用。 問題是,對應的函數調用-我已經通過了調試測試階梯,他們執行沒有問題。 所以問題一定是間諜沒有正確地依附自己。
我不知道如何讓他們被調用。 我試過在被測試的文件fs.unlinkFileSync()
import * as fs from 'fs'
和fs.copyFileSync()
/ fs.unlinkFileSync()
。 我試過將beforeAll()
放在beforeAll()
函數中。 這兩種解決方案都沒有幫助。 我在同一個測試規范中嘲笑其他幾個不直接相關的方法調用,它們都按預期工作; 只有這個不是,我不知道為什么。
我的package.json
包括以下依賴項:
"scripts": {
"test": "tsc && jasmine",
},
"devDependencies": {
"@types/jasmine": "^3.5.10",
"@types/node": "^13.7.7",
"@types/pg": "^7.14.3",
"copyfiles": "^2.2.0",
"jasmine": "^3.5.0",
"jasmine-core": "^3.5.0",
"jasmine-ts": "^0.3.0",
"js-yaml": "^3.13.1",
"mock-fs": "^4.11.0",
"morgan": "^1.10.0",
"nodemon": "^2.0.2",
"swagger-ui-express": "^4.1.3",
"ts-node": "^8.7.0",
"typescript": "^3.8.3"
},
"dependencies": {
"@types/express": "^4.17.3",
"chokidar": "^3.3.1",
"cors": "^2.8.5",
"csv-writer": "^1.6.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"murmurhash": "0.0.2",
"pg": "^7.18.2",
"pg-format": "^1.0.4",
"winston": "^3.2.1"
}
我的jasmine.json
看起來像這樣:
{
"spec_dir": "dist",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": true
}
和tsconfig
:
{
"compilerOptions": {
"experimentalDecorators": true,
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"typeRoots": [
"node_modules/@types",
"node_modules/@types/node"
],
},
"lib": [
"es2015"
]
}
Jasmine spyOn
函數返回一個Spy
類對象,它不代表任何函數調用,但它有關於spyOn
函數的輔助方法。 您必須直接向fs.<function>
調用expect
以檢查它是否被調用:
import * as fs from 'fs';
import * as path from 'path';
import { myFunction } from '../src/myFunction';
describe('MyFunc', () => {
it("tests something involving input/output", () => {
spyOn(fs, 'copyFileSync');
spyOn(fs, 'unlinkSync');
myFunction();
expect(fs.copyFileSync).toHaveBeenCalledWith(
path.resolve('file1.csv'),
path.resolve('otherDir/file2.csv')
);
expect(fs.unlinkSync).toHaveBeenCalled();
});
});
您可以使用此 GitHub 存儲庫測試一個簡單的重現示例: https : //github.com/clytras/fs-jasminte-ts-mocking
git clone https://github.com/clytras/fs-jasminte-ts-mocking.git
cd fs-jasminte-ts-mockin
npm i
npm run test
更新
看來,你有esModuleInterop
設置為true
內部tsconfig.json
。 這意味着當您import * as fs from 'fs'
,不會保留fs
對象的單個實例。
您可以將esModuleInterop
設置為false
並使您的測試通過toHaveBeenCalled
和toHaveBeenCalledWith
,但這可能會破壞您項目的其他一些功能。 您可以在此處了解有關esModuleInterop
功能的更多信息了解 tsconfig 文件中的 esModuleInterop 。
如果您不想將esModuleInterop
設置為false
,那么您必須像在 ES6 Javascript 中一樣導入fs
,如下所示:
import fs from 'fs'; // Use plain default import instead of * as
import path from 'path';
import { myFunction } from '../src/myFunction';
describe('MyFunc', () => {
it("tests something involving input/output", () => {
spyOn(fs, 'copyFileSync');
spyOn(fs, 'unlinkSync');
myFunction();
expect(fs.copyFileSync).toHaveBeenCalledWith(
path.resolve('file1.csv'),
path.resolve('otherDir/file2.csv')
);
expect(fs.unlinkSync).toHaveBeenCalled();
});
});
我還注意到您的配置文件中缺少這些內容:
如果不這樣做,則必須使用jasmine-console-reporter
:
npm i -D jasmine-console-reporter
package.json
test
腳本更改為"test": "tsc && jasmine --reporter=jasmine-console-reporter"
在jasmine.json
,將ts-node/register/type-check.js
到 helpers 中,例如:
{ ... "helpers": [ "helpers/**/*.js", "../node_modules/ts-node/register/type-check.js" ], }
現在你的測試應該通過了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.