import { NestFactory } from '#nestjs/core';
import { RunnerModule } from './runner.module';
async function bootstrap() {
const app = await NestFactory.create(RunnerModule);
await app.listen(3000);
}
bootstrap();
So this is the main ts. I want to test it but i dont know how to test that app is listening on port 3000
mock the path
there's nothing to test in that file.
Instead, you could write an integration test for RunnerModule, just like the docs shows for E2E tests.
I don't get why you want to test if the server is listening to some port since this piece logic was not written by you, that is something that the framework should take care.
I'm trying to write Jest tests for a Fastify project. But I'm stuck with the example code failing with an ambiguous error: "● default root route".
// root.test.ts
import { build } from '../helper'
const app = build()
test('default root route', async () => {
const res = await app.inject({
url: '/'
})
expect(res.json()).toEqual({ root: true })
})
// helper.ts
import Fastify from "fastify"
import fp from "fastify-plugin"
import App from "../src/app"
export function build() {
const app = Fastify()
beforeAll(async () => {
void app.register(fp(App))
await app.ready()
})
afterAll(() => app.close())
return app
}
// console error:
FAIL test/routes/root.test.ts (8.547 s)
● default root route
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
What am I doing wrong?
After running --detectOpenHandles, Jest reported that open ioredis connections were timing out.
I hooked up ioredis instances to Fastify lifecycle with fastify-redis and the test passed.
I have a very simple code structure like this
TestWorks.ts
const axios = require('axios');
export class TestWorks{
async getUsersList(param1:TestModel, userDetail:any){
console.log("BEGIN -- ... ");
And then this is my test class
MyTest.ts
const testworks = require("../src/interfaces/TestService/TestWorks");
it('Get Users', async () => {
var x = await testworks.getUsersList({}, {});
expect(x).to.be.an("object");
});
but I am seeing the following error, unable to figure out what the issue could be. The paths are definitely right, not an issue with the file paths of where the files are
Get Users:
TypeError: testworks.getUsersList is not a function
at C:\Users\xxxxxx\Documents\xxxxx\test\test-server.test.ts:53:28
testworks refers to the module (or whatever TypeScript exports) because you use require(). You should use import for TypeScript modules.
import { TestWorks } from '../src/interfaces/TestService/TestWorks';
I'm using node with TypeScript on my back end and Jest and Supertest as my test framework on my back end.
When I'm trying to test I have the result pass but I get an error at the end. Here's the result:
PASS test/controllers/user.controller.test.ts
Get all users
✓ should return status code 200 (25ms)
console.log node_modules/#overnightjs/logger/lib/Logger.js:173
[2019-12-05T04:54:26.811Z]: Setting up database ...
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.284s
Ran all test suites.
server/test/controllers/user.controller.test.ts:32
throw err;
^
Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1104:14)
npm ERR! Test failed. See above for more details.
Here's my test code:
import request from "supertest";
import { AppServer } from '../../config/server';
const server = new AppServer();
describe('Get all users', () => {
it('should return status code 200', async () => {
server.startDB();
const appInstance = server.appInstance;
const req = request(appInstance);
req.get('api/v1/users/')
.expect(200)
.end((err, res) => {
if (err) throw err;
})
})
})
Here's my server setup. I'm using overnightjs on my back end.
I created a getter to get the Express instance. This is coming from overnight.js.
// this should be the very top, should be called before the controllers
require('dotenv').config();
import 'reflect-metadata';
import { Server } from '#overnightjs/core';
import { Logger } from '#overnightjs/logger';
import { createConnection } from 'typeorm';
import helmet from 'helmet';
import * as bodyParser from 'body-parser';
import * as controllers from '../src/controllers/controller_imports';
export class AppServer extends Server {
constructor() {
super(process.env.NODE_ENV === 'development');
this.app.use(helmet());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: true }));
this.setupControllers();
}
get appInstance(): any {
return this.app;
}
private setupControllers(): void {
const controllerInstances = [];
// eslint-disable-next-line
for (const name of Object.keys(controllers)) {
const Controller = (controllers as any)[name];
if (typeof Controller === 'function') {
controllerInstances.push(new Controller());
}
}
/* You can add option router as second argument */
super.addControllers(controllerInstances);
}
private startServer(portNum?: number): void {
const port = portNum || 8000;
this.app.listen(port, () => {
Logger.Info(`Server Running on port: ${port}`);
});
}
/**
* start Database first then the server
*/
public async startDB(): Promise<any> {
Logger.Info('Setting up database ...');
try {
await createConnection();
this.startServer();
Logger.Info('Database connected');
} catch (error) {
Logger.Warn(error);
return Promise.reject('Server Failed, Restart again...');
}
}
}
I read this question - that's why I called the method startDB.
So I figured out and the solution is quite easy. I can't explain why though.
This req.get('api/v1/users/') should be /api/v1/users - you need a leading /.
For Frontend...
If you are making use of axios and come across this error, go to the testSetup.js file and add this line
axios.defaults.baseURL = "https://yourbaseurl.com/"
This worked for me. So, typically, this is a baseURL issue.
I had this error in my React frontend app tests.
I was using React testing library's findBy* function in my assert:
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
After I changed it to:
await waitFor(async () => {
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
});
the error is gone.
I don't know exactly why, but maybe it will help someone
UPDATE: I was mocking fetch incorrectly, so my test called real API and caused that error
I put this line in my setupTests file:
global.fetch = jest.fn()
It mocks fetch for all tests globally. Then, you can mock specific responses right in your tests:
jest.mocked(global.fetch).mockResolvedValue(...)
// OR
jest.spyOn(global, 'fetch').mockResolvedValue(...)
Slightly different issue, but same error message...
I was having this error when using node-fetch when trying to connect to my own localhost (http://localhost:4000/graphql), and after trying what felt like everything under the sun, my most reliable solution was:
using this script in package.json: "test": "NODE_ENV=test jest --watch"
If the terminal shows connection error I just go to the terminal with Jest watching and press a to rerun all tests and they pass without any issue.
¯\_(ツ)_/¯
Success rate continued to improve by renaming the testing folder to __tests__ and moving my index.js to src/index.js.
Very strange, but I am too exhausted to look at the Jest internals to figure out why.
The rules for supertest are the same as the rules for express. OvernightJS does not require any leading or ending "/" though.
For anyone landing on this, but not having issues with trailing slashes:
jest can also return a ECONNREFUSED when your express app takes some time (even just a second) to restart/init. If you are using nodemon like me, you can disable restarts for test files like --ignore *.test.ts.
This error also occurs if you have not set up a server to catch the request at all (depending on your implementation code and your test, the test may still pass).
I didn't get to the bottom of this error - it wasn't related to the (accepted) leading slash answer.
However, my "fix" was to move the mocks up into the suite definition - into beforeAll and afterAll for cleanup between tests).
Before, I was mocking (global.fetch) in each test, and it was the last test in the suite to use the mock that would cause the error.
In my case, the issue was related to package react-inlinesvg. Package makes a fetch request to get the svg file and since server is not running, it gets redirected to default 127.0.0.1:80.
I mocked react-inlinesvg globally to output props including svg filename to assert in testing.
jest.mock('react-inlinesvg', () => (props) => (
<svg data-testid="mocked-svg">{JSON.stringify(props)}</svg>
));
I am having trouble mocking a simple dependency generator function.
//generatorFunction.js
export default ()=>({execute: (arg1)=>Promise.resolve(arg1)})
//actualFunction.js
import generate from 'generatorFunction'
export default (arg1)=>generate(arg1)
//actualFunction.test.js
import actualFunction from './actualFunction'
import generatorFunction from './generatorFunction'
const resultingGeneratedFunction = generatorFunction();
jest.mock('generatorFunction', ()=>jest.fn(()=>({execute: ()=>Promise.resolve()})))
it('calls generateFunction', function(done){
actualFunction(1).then(()=>{
expect(resultingGeneratedFunction.execute).toHaveBeenCalledOnce()
done()
})
})
which errors out as execute is never called, although when I console log inside of actualFunction is saw that execute was called.
The problem is that jest cant know you using a promise somewhere in your test. You have either return the promise from you use async/await. Have a look at the docs
import actualFunction from './actualFunction'
import generate from 'generatorFunction'
jest.mock('generatorFunction', ()=>jest.fn(()=>({execute: ()=>Promise.resolve()})))
it('calls generateFunction', function(){
return actualFunction(1).then(()=>{
expect(generateFunction.execute).toHaveBeenCalledOnce()
})
})
import actualFunction from './actualFunction'
import generate from 'generatorFunction'
jest.mock('generatorFunction', ()=>jest.fn(()=>({execute: ()=>Promise.resolve()})))
it('calls generateFunction', async function(){
const value = await actualFunction(1)
expect(generateFunction.execute).toHaveBeenCalledOnce()
})