Mock Mongoose multiple calls in Nest js service Jest - unit-testing

I have this simple method in service class(Nest js) which I want to unit test
constructor(#InjectModel(Task.name) private tasksModel: Model<Task>) {}
async findAll(): Promise<WorkflowDto[]> {
const workflows = await this.workflowModel.find().exec();
return workflows.map((workflow) => workflow.toObject());
}
Below is my spec file code
it('should return maching tasks', async () => {
const taskDto: any =[somevalue]
jest.spyOn(model, 'find').mockImplementation(() => taskDto)
var findAll = await service.findAll();
but getting the error
TypeError: this.workflowModel.find(...).exec is not a function
I want to mock find() and exec() method of mongoose model in my spec file..

Related

How to get code coverage metrics from integration tests using serverless-offline and Supertest?

I'm building an AWS Lambda function and trying to write some integration tests for it. The Lambda function is running locally using serverless-offline plugin and simply receive a GET request with some query parameters. I'm using Jest and Supertest to write my integration tests as follow:
import request from 'supertest';
describe('User position handler', () => {
it('should return history', () => {
const server = request('http://0.0.0.0:4000');
return server
.get(`/local/position?type=month&period=3`)
.expect(200)
.expect((response) => {
console.log('RESPONSE', response);
expect(response.body).toHaveLength(3);
});
});
});
The problem is that when I run Jest with collect coverage option the code reached by the request sent with Supertest is not computed in the metrics. Running jest --collectCoverage the result is:
The question is that I know that, for example, infra/handlers/user-position.ts is being reached and covered more than 0% statements, but the coverage metrics don't show as expected. Also, I know that user-monthly-position.service.impl.ts is being reached at some point of the flow since this service is responsible for returning data from an external service and the response from Supertest is returning data. The green lines are from files covered by unit test that are using only Jest (and not Supertest, obviously)
I know that when using Supertest with Express framework I can pass an instance of the Express app. to the request function. This way I think that Jest can "inspect" or "instrument" the function call stack to measure the coverage (code sample below). But how can I do the same passing the URL of a running serverless-offline Lambda?
const request = require('supertest');
const assert = require('assert');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'john' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
Here the code of my handler function:
export default async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
await cacheService.bootstrapCache();
const userMonthlyPositionService = new UserMonthlyPositionServiceImpl(
cacheService.connectionPool,
);
const getUserMonthlyPositionHistory = new GetUserMonthlyPositionHistory(
userMonthlyPositionService,
);
const result = await getUserMonthlyPositionHistory.execute({
cblc: 999999,
period: 3,
type: 'month',
});
return buildResponse(200, result);
};
My question is: how can I collect right code coverage metrics from Jest using Supertest and Serverless Framework? Am I forgetting a detail? Thanks!

Test Jest and NestJs

I have a service (in Nestjs) and I want test the function exception whit Jest.
My service:
class MyService{
public throwError(ms: string) {
throw new UnprocessableEntityException(ms);
}
}
And I want test it, but I don't know how to do it.
I feel like jest's docs point this out pretty well, but as a quick example, for the above code you'd just need something simple like
describe('MyuService', () => {
describe('throwError', () => {
it('should throw an UnprocessableEntityException', () => {
const myService = new MyService();
expect(
() => myService.throwError('some string')
).toThrow(new UnprocessableEntityException('some string'));
})
})
})
For even more examples, there's a git repo here with a lot of different samples from rxjs to typeorm to graphql, sync and async

VueComponent.mounted : TypeError: Cannot read property 'get' of undefined in mounted hook

I am using jest for unit testing in nuxt js
I have mounted hook like this
async mounted(){
try{
var response = await this.$axios.get("api_url here");
this.result = response.data;
} catch(e){
console.log("Exception: ",e)
}
}
when i do unit test for it my code is . utnit.spec.js
jest.mock("axios", () => ({
get: () => Promise.resolve({ data: [{ val: 1 }] })
}));
import { mount } from '#vue/test-utils';
import file from '../filefile';
import axios from "axios";
describe('file', () => {
test('check comp. working correctly', () => {
var wrapper = mount(file);
afterEach(() => {
wrapper.destroy()
})
})
})
I am getting this warn there and there is no data in the results
Exception: TypeError: Cannot read property 'get' of undefined
at VueComponent.mounted
how do I know what is the problem here, is this I can not access axios in the unit file Is there any specific way to test Axios in mounted hook
The error means that it's this.$axios.get that is not available, not axios.get. The component relies on Axios plugin that is commonly installed in Vue application entry point or Nuxt configuration.
It can be installed for localVue Vue instance in tests, or be supplied directly to the component:
var wrapper = mount(file, { mocks: { $axios: axios } });
Also, the mock will fail if Axios is used as axios() somewhere because default import is expected to be a function:
jest.mock("axios", () => Object.assign(
jest.fn(),
{ get: jest.fn() }
));
axios.get is Jest spy, the implementation is mocked per test depending on the use and isn't limited to hard-coded Promise.resolve({ data: ... }) supplied in the mock.

How to mock Fastify plugin

I am trying to write unit testing for fastify application which also has custom fastify plugin.
Is there a way we can mock fastify plugin? I tried mocking using Jest and Sinon without much success.
Giorgios link to the file is broken, the mocks folder is now absent from the master branch. I dug the commit history to something around the time of his answer and I found a commit with the folder still there. I leave it here for those who will come in the future!
This is what works for me
Setup your plugin according to Fastify docs https://www.fastify.io/docs/latest/Reference/Plugins/
// establishDbConnection.ts
import fp from 'fastify-plugin';
import {FastifyInstance, FastifyPluginAsync} from 'fastify';
import { initDbConnection } from './myDbImpl';
const establishDbConnection: FastifyPluginAsync = async (fastify: FastifyInstance, opts) => {
fastify.addHook('onReady', async () => {
await initDbConnection()
});
};
export default fp(establishDbConnection);
mock the plugin with jest, make sure you wrap the mock function in fp() so that Fastify recognizes it as a plugin.
// myTest.ts
import fp from 'fastify-plugin';
const mockPlugin = fp(async () => jest.fn());
jest.mock('../../../fastifyPlugin/establishDbConnection', (() => {
return mockPlugin;
}));
Your question is a bit generic but if you are using Jest it must be enough for mocking a fastify plugin. You can take a look in this repo and more specifically this file . This is a mock file of fastify and you add the registered plugins and in the specific example addCustomHealthCheck and then in your test files you can just call jest.mock('fastify').
You do not give a specific use case and there are lot of reasons you might want to mock a plugin. The nature of the plugin to be mocked is important to giving a good answer. Because I don't know that specific information I will show how to mock a plugin that creates a decorator that stores data that can be retrieved with fastify.decorator-name. This is a common use case for plugins that connect to databases or store other widely needed variables.
In the below case, the goal is to test a query function that queries a db; a plugin stores the connection information via a fastify decorator. So, in order to unit test the query we specifically need to mock the client data for the connection.
First create an instance of fastify. Next, set up a mock to return the desired fake response. Then, instead of registering the component with fastify (which you could also do), simply decorate the required variables directly with mock information.
Here is the function to be tested. We need to mock a plugin for a database which creates a fastify decorator called db. Specifically, in the below case the function to be tested uses db.client:
const fastify = require("fastify")({ //this is here to gather logs
logger: {
level: "debug",
file: "./logs/combined.log"
}
});
const HOURS_FROM_LOADDATE = "12";
const allDataQuery = `
SELECT *
FROM todo_items
WHERE a."LOAD_DATE" > current_date - interval $1 hour
`;
const queryAll = async (db) => {
return await sendQuery(db, allDataQuery, [HOURS_FROM_LOADDATE]);
};
//send query to db and receive data
const sendQuery = async (db, query, queryParams) => {
var res = {};
try {
const todo_items = await db.client.any(query, queryParams);
res = todo_items;
} catch (e) {
fastify.log.error(e);
}
return res;
};
module.exports = {
queryByAsv
};
Following is the test case. We will mock db.client from the db plugin:
const { queryAll } = require("../src/query");
const any = {
any: jest.fn(() => {
return "mock response";
})
};
describe("should return db query", () => {
beforeAll(async () => {
// set up fastify for test instance
fastify_test = require("fastify")({
logger: {
level: "debug",
file: "./logs/combined.log",
prettyPrint: true
}
});
});
test("test Query All", async () => {
// mock client
const clientPromise = {
client: any
};
//
fastify_test.decorate("db", clientPromise);
const qAll = await queryAll(fastify_test.db);
expect(qAll).toEqual("mock response");
});
});

unit testing express route controller with multiple external API requests

in my unit tests I need to mock some http requests.
const getDashboardData = (req, res) => {
const activeListings = articlesLib.getLiveArticles(req.user.id)
const soldThisMonthPromise = articlesLib.getSoldArticles(req.user.id, {})
const userDrafts = articlesLib.getDrafts(req.user.id)
return Promise.all([activeListings, soldThisMonthPromise, userDrafts])
.then((data) => {
res.render(`${__dirname}/home`, {
viewData: data
})
})
}
router.get('/', getDashboardData)
Each request from articleLib has the same url, but uri is different. I wanted to mock it with nock, but it doesn't support multiple mock for the same base url. Is there any tool that mock a response when given http request is detected?