Simple TypeScript Testing with Chutzpah not Working - unit-testing

I'm trying to run the most basic of TypeScript tests using Jasmine and Chutzpah and I just can't get it to work. Here is the source file:
class Simple {
public easyTest() {
return 5;
}
}
Here is the spec:
/// <reference path="../../../scripts/typings/jasmine/jasmine.d.ts" />
/// <reference path="../../../src/typescript/classSimple.ts" />
describe("Simple Calculations", () => {
it("should return true", () => {
var simpl = new Simple();
expect(simpl.easyTest()).toBe(5);
});
});
Here is my chutzpah.json file:
{
"RootReferencePathMode": "SettingsFileDirectory",
"Framework": "jasmine",
"Compile": {
"Mode": "External",
"Extensions": [ ".ts" ],
"ExtensionsWithNoOutput": [ ".d.ts" ]
},
"References": [
{ "Path": "../../../src/typescript/classSimple.ts" }
],
"Tests": [
{ "Path": "simpleSpec.ts" }
],
"EnableTracing": true
}
Here is the folder structure
TestProject.sln
-src
--typescript
---classSimple.ts
-tests
--jasmine
---typescript
----chutzpah.json
----simpleSpec.ts
This VS.NET project is set to compile TypeScript upon save and I'm physically looking at the transpiled JavaScript output: classSimple.js in the exact same directory next to classSimple.ts. Yet when I run the spec using Chutzpah I get the following:
Message:Chutzpah run started in mode Execution with parallelism set to
4 Message:Building test context for
C:\dev\TestProject\tests\jasmine\typescript\simpleSpec.ts
Message:Building test context for
'C:\dev\TestProject\tests\jasmine\typescript\simpleSpec.ts'
Message:Test file
c:\dev\TestProject\tests\jasmine\typescript\simplespec.ts matched test
file path from settings file Message:Investigating reference file path
'../../../src/typescript/classSimple.ts' Message:Added file
'C:\dev\TestProject\src\typescript\classSimple.ts' to referenced
files. Local: True, IncludeInTestHarness: True Message:Processing
referenced file 'C:\dev\TestProject\src\typescript\classSimple.ts' for
expanded references Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\jasmine\v2\jasmine_favicon.png' to referenced files Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\jasmine\v2\boot.js'
to referenced files Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\jasmine\v2\jasmine-html.js'
to referenced files Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\jasmine\v2\jasmine.js'
to referenced files Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\jasmine\v2\jasmine.css'
to referenced files Message:Added framework dependency
'C:\Users\myself\AppData\Local\Microsoft\VisualStudio\14.0\Extensions\mfv4e3ra.luv\TestFiles\chutzpah_boot.js'
to referenced files Message:Finished building test context for
C:\dev\TestProject\tests\jasmine\typescript\simpleSpec.ts Error: 0 :
Time:22:47:48.6888513; Thread:23; Message:Can't find location for
generated path on C:\dev\TestProject\src\typescript\classSimple.ts
Warning: 0 : Time:22:47:48.6978503; Thread:23; Message:Chutzpah
determined generated .js files are missing but the compile mode is
External so Chutzpah can't compile them. Test results may be wrong.
Information: 0 : Time:22:47:48.7038522; Thread:23; Message:Found
generated path for
C:\dev\TestProject\tests\jasmine\typescript\simpleSpec.ts at
c:\dev\TestProject\tests\jasmine\typescript\simpleSpec.js Error: 0 :
Time:22:47:48.7088508; Thread:23; Message:Couldn't find generated path
for C:\dev\TestProject\src\typescript\classSimple.ts at
And that's it - it just cuts off on the end and nothing happens. The thing is, I see the .js files exactly in the location stated within the trace above, but Chutzpah is claiming Couldn't find generated path for...
This is as simple as it gets for unit testing. I know the tests work independently of the .ts files because if I run just the .js files the tests pass.
What am I doing incorrectly?

Thanks for posting the very detailed repro. You are hitting an issue I have seen a couple times. Since your chutzpah.json is nested in your test folder you need to specify the folder path mapping that chutzpah should use for determining how to map from source to output folder. To do this just change your chutzpah.json to:
{
"RootReferencePathMode": "SettingsFileDirectory",
"Framework": "jasmine",
"Compile": {
"Mode": "External",
"Extensions": [ ".ts" ],
"ExtensionsWithNoOutput": [ ".d.ts" ],
"Paths": [
{ "SourcePath": "../../../", "OutputPath": "../../../"}
]
},
"References": [
{ "Path": "../../../src/typescript/classSimple.ts" }
],
"Tests": [
{ "Path": "simpleSpec.ts" }
],
"EnableTracing": true,
"TraceFilePath": "trace.txt"
}
The other workaround would be to just place the chutzpah.json at the root of your project.
I need to look into making Chutzpah better to avoid this. I think I will look at letting chutzpah in this situation just assume the file is co-located to avoid this common pitfall.

Google led me here for a similar issue:
Some new tests in my Chutzpah project are written in TypeScript and compiled into a single outfile:
tsconfig.json
"compilerOptions": {
"noImplicitAny": true,
"target": "es5",
"module": "none",
"outFile": "./Tests/mytests-ts.js",
"sourceMap": true
}
Chutzpah couldn't find the *.ts files
Chutzpah Error: System.IO.FileNotFoundException: Couldn't find generated path for D:\Code\ChutzpahProject\Scripts\DateServiceMock.ts
until I used the Paths option:
chutzpah.json
"Compile": {
"Extensions": [ ".ts" ],
"ExtensionsWithNoOutput": [ ".d.ts" ],
"Executable": "build-ts.cmd",
"Paths": [
{ "OutputPath": "Tests/mytests-tests-ts.js" }
]
},
This feels like it could have been a comment to #matthew-manela's answer...I think.

Related

Enable jasmine/globals in unit testing

In my .eslintrc.json file(which inherits from a root .eslintrc.json file), I have this configuration
"extends": ["<root>/.eslintrc"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"parserOptions": {
"project": ["<path>/tsconfig.*?.json"]
},
"settings": {
"disable/plugins": ["jest"]
}
},
]
}
The root .eslintrc.json file has
"plugins": ["#nrwl/nx", "jest", "jasmine"],
"extends": ["plugin:jest/recommended", "plugin:jasmine/recommended"],
For my project I only need to use jasmine and not jest. While the test runs successfully, I get a lint error of
error Illegal usage of global `spyOn`, prefer `jest.spyOn` jest/no-jasmine-globals
On adding rules: {"jest/no-jasmine-globals": "off"} and "env": { "jasmine-globals": true } I get another lint error that says jasmine-globals could not be identified
I need to suppress the jest plugins and allow jasmine alone. What are the modifications that I need to do?

Jest: testEnvironmentOptions cannot be read

I'm getting the following error with Jest, but unclear why even after adding the testEnvironmentOptions
TypeError: Cannot read properties of undefined (reading 'testEnvironmentOptions')
at new JSDOMEnvironment (node_modules/jest-environment-jsdom/build/index.js:72:28)
at async TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at async runJest (node_modules/#jest/core/build/runJest.js:404:19)
Here is my Jest config in my package.json:
"jest": {
"moduleNameMapper": {
"^#/(.*)$": "<rootDir>/$1",
"^~/(.*)$": "<rootDir>/$1",
"^vue$": "vue/dist/vue.common.js"
},
"testEnvironment": "jsdom",
"testEnvironmentOptions": {
"browsers": [
"chrome",
"firefox",
"safari"
]
},
"moduleFileExtensions": [
"vue",
"js",
"json"
],
"transformIgnorePatterns": [
"/node_modules/(?!crypto-random-string)"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"collectCoverage": true,
"collectCoverageFrom": [
"<rootDir>/src/**/*.vue",
"<rootDir>/src/**/*.js"
]
}
Make sure you have both packages jest and jest-environment-jsdom installed in the same version. The latter is required to be installed separately from jest version 28 on. I ran into the same issue when downgrading jest to 27.x but not jest-environment-jsdom. Have a look at the version 27 to 28 upgrade guide about using JSDOM test environment.
I had different versions of local jest and global jest, jest-environment-jsdom was not installed globally. This caused me the issues. Running it locally via
./node_modules/jest/bin/jest.js src/my-test.spec.ts
or updating global jest packages did the job for me.
I see that this is mentioned in one of the comments above, but somehow I missed it and spent too much time on it so posting it here
For me running
npx browserslist#latest --update-db
did the job

Using a (Zustand) function mock with Jest results in "TypeError: create is not a function"

I'm following the Zustand wiki to implement testing, but the provided solution is not working for a basic test for app rendering. My project is built on top of the Electron React Boilerplate boilerplate project.
Here's the full error. Jest is using node with experimental-vm-modules because I followed the the Jest docs to support ESM modules.
$ cross-env NODE_OPTIONS=--experimental-vm-modules jest
(node:85003) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
jest-haste-map: Haste module naming collision: myproject
The following files share their name; please adjust your hasteImpl:
* <rootDir>/package.json
* <rootDir>/src/package.json
FAIL src/__tests__/App.test.tsx
● Test suite failed to run
TypeError: create is not a function
12 | }
13 |
> 14 | const useNotifs = create<NotifsState>(
| ^
15 | // devtools(
16 | (set) => ({
17 | notifStore: notifsDefault.notifStore,
at src/state/notifs.ts:14:19
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:387:19)
at _run10000 (node_modules/#jest/core/build/cli/index.js:408:7)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 11.882 s
Ran all test suites.
error Command failed with exit code 1.
At the top of the notifs.ts file, Zustand is imported normally with import create from 'zustand'.
Jest config in package.json:
...
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/mocks/fileMock.js",
"\\.(css|less|sass|scss)$": "identity-obj-proxy",
"zustand": "<rootDir>/src/__mocks__/zustand.js",
},
"transformIgnorePatterns": [
"node_modules/(?!(zustand)/)",
"<rootDir>/src/node_modules/"
],
"moduleDirectories": [
"node_modules",
"src/node_modules"
],
"moduleFileExtensions": [
"js",
"jsx",
"ts",
"tsx",
"json"
],
"moduleDirectories": [
"node_modules",
"src/node_modules"
],
"extensionsToTreatAsEsm": [
".ts",
".tsx"
],
...
I have left the ./src/__mocks__/zustand.js file exactly the same as from the Zustand wiki Testing page. I receive the same error whether or not I have zustand in the transformIgnorePatterns.
My Babel configuration includes [require('#babel/plugin-proposal-class-properties'), { loose: true }], in the plugins section, and output.library.type is 'commonjs2'
My tsconfig.json has compilerOptions.module set to "CommonJS", and the project's package.json "type" field is set to "commonjs".
Dependency versions:
"#babel/core": "^7.12.9",
"#babel/preset-env": "^7.12.7",
"#babel/preset-react": "^7.12.7",
"#babel/preset-typescript": "^7.12.7",
"#babel/register": "^7.12.1",
"#babel/plugin-proposal-class-properties": "^7.12.1",
"#testing-library/jest-dom": "^5.11.6",
"#testing-library/react": "^11.2.2",
"babel-jest": "^27.0.6",
"babel-loader": "^8.2.2",
"jest": "^27.0.6",
"regenerator-runtime": "^0.13.9",
"source-map-support": "^0.5.19",
"typescript": "^4.0.5",
"webpack": "^5.5.1",
"zustand": "^3.5.5"
I don't know what else could be relevant, just let me know if anything else is needed. Any and all help appreciated, thanks for your time.
To do this you should use the actual store of your app
const initialStoreState = useStore.getState()
beforeEach(() => {
useStore.setState(initialStoreState, true)
})
useStore.setState({ me: memberMockData, isAdmin: true })
The documentation seems off. So don't follow it.
use jest 28.0.0-alpha.0 will simply resolve the issue.
I think the problem is zustand uses '.mjs' as the entry point.

Why Chutzpah does not recognize all TypeScript tests?

I have a project with the following chutzpah.json:
{
"Framework": "jasmine",
"TestHarnessReferenceMode": "AMD",
"TestHarnessLocationMode": "SettingsFileAdjacent",
"EnableTestFileBatching": true,
"References": [
{ "Path": "node_modules/es6-shim/es6-shim.min.js" },
{ "Path": "node_modules/zone.js/dist/zone.min.js" },
{ "Path": "node_modules/reflect-metadata/Reflect.js" },
{ "Path": "node_modules/systemjs/dist/system.js" },
{ "Path": "system-config.js" }
],
"CodeCoverageExcludes": ["node_modules/*"],
"Tests": [
{ "Path": "app", "Includes": [ "*.spec.ts" ] }
]
}
and the following tests files
Test explorer just shows tests stored in the first file
If I try to run the the command of the VSTest I get the same result:
If I call the command setting the name of the file (e.g. "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" app\InspectionDataView.spec.ts /UseVsixExtensions:true ), the tests in the file run.
Extra point:
I tried to run the test directly with Chutzpah.console.exe, this is what I got:
What am I missing here ?
Note: Using VS 2015 Update 3
Chutzpah does not run TypeScript. It "supports" it, but you have to add this support in the chutzpah.json.
Why the first test suite succeeds? Perhaps it is written in pure ES5 (Without ES6/TS classes, interfaces, etc).
I did set up chutzpah support for typescript from this repo https://github.com/mmanela/chutzpah/tree/master/Samples/Compilation/TypeScript
Basically, in short:
create a compile.bat that transpiles TS to ES5. Normally - tsc.exe with or without tsconfig.json
add "Compile" section as seen in https://github.com/mmanela/chutzpah/blob/master/Samples/Compilation/TypeScript/chutzpah.json
this shall transpile TS to ES5 every time you run chutzpah.console.exe

Karma/Jasmine testcases failing due to ngIdle module

Error: [$injector:modulerr] Failed to instantiate module ngIdle due to:
Error: [$injector:nomod] Module 'ngIdle' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
What is it that I am missing? If I don't include ngIdle module and remove the code for it's implementation then all my karma/jasmine tests are passing but with ngIdle included all of my 100+ testcases are failing and giving the above error. I have included ngIdle in karma.conf.js in this order
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-touch/angular-touch.js',
'app/bower_components/angular-animate/angular-animate.js',
'app/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/revolunet-angular-carousel/lib/angular-mobile.js',
'app/bower_components/revolunet-angular-carousel/src/angular-carousel.js',
'app/bower_components/jquery/dist/jquery.js',
'app/bower_components/angular-cookies/angular-cookies.min.js',
'app/bower_components/ng-idle/angular-idle.min.js',
'app/bower_components/ng-grid/ng-grid-2.0.11.min.js',
'app/js//*.js',
'test/spec//*.js'
],
Below is my bower.json so you get idea about the versions I am using if that is related
{
"name": "combo",
"version": "0.5.1",
"dependencies": {
"angular": "~1.3",
"angular-route": "~1.3",
"angular-touch": "~1.3",
"angular-animate": "~1.3",
"angular-resource": "~1.3",
"angular-cookies": "~1.3",
"angular-bootstrap": "~0.11.0",
"revolunet-angular-carousel": "~0.2.2",
"ng-grid": "~2.0.7",
"ng-idle": "latest",
"video.js": "~4",
"highcharts": "~3.0.7",
"jquery": "~2",
"jquery-ui": "~1.10.4",
"jqueryui-touch-punch": "git://github.com/furf/jquery-ui-touch-punch.git",
"angular-snap": "~1.4.1",
"snapjs": "latest"
},
"devDependencies": {
"angular-mocks": "~1.3",
"angular-scenario": "~1.3"
},
"resolutions": {
"angular": "~1.2.10",
"angular-touch": "~1.2.10",
"jquery": "^1.8.0"
}
}
You have to add angular-idle.min.js to your karma.conf.js.
files: [
//Configs
'config.js',
'lib/angular/angular.min.js',
'lib/angular-mocks/angular-mocks.js',
'lib/moment/moment.js',
'lib/ng-idle/angular-idle.min.js',
'lib/angular-moment/angular-moment.js',
// ... another libraries
],