Replies: 21 comments 46 replies
-
@molebox adding on here. I just went and followed the singleton guide and added onto a repo where I've documented the error I've been seeing. Ultimately, it appears the issue occurs when attempting to use jest's https://github.com/uptownhr/prisma-mock-deep-error Branch
|
Beta Was this translation helpful? Give feedback.
-
Hello @molebox , // user.ts
// The real request
prisma.posts.findMany({select: {title: true}}) // /__tests__/user.ts
// The mocked request
prismaMock.posts.findMany.mockResolvedValue([{title: "Hello"}, {title: "World"} ])
ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ
// here it is asking for all the columns because it is not aware of the `select` |
Beta Was this translation helpful? Give feedback.
-
Hi guys! How to test which arguments were passed in my prismaMock.user.create function? 🤔 prismaMock.user.create.mockResolvedValue(mockData);
// is right?
expect(prismaMock.user.create).toHaveBeenCalledWith(mockData); I'm doing this while I don't find a solution: import { prisma } from '~shared/infra/database/prisma/client';
...
beforeEach(() => {
prisma.user.create = jest.fn();
});
...
describe('add', () => {
test('should be called add with correct params', async () => {
jest.spyOn(prisma.user, 'create').mockResolvedValue(mockData);
await repository.add({
name: 'any_name',
email: 'any_email',
admin: true
});
expect(prisma.user.create).toHaveBeenCalledWith({
data: { name: 'any_name', email: 'any_email', admin: true }
});
});
}); |
Beta Was this translation helpful? Give feedback.
-
Hi, This is the query I want to test: await prisma.user.update({
where: {
id: user.id
},
data: { /* some data */ },
select: {}
}).catch(error => { /* do some stuff */ }); This is what I tried: prisma.user.update.mockRejectedValue(new Error()); This however results in a What would be the right way to do this? I want to test the stuff in the |
Beta Was this translation helpful? Give feedback.
-
Hi I found these error both of singleton and dependency injection. I also set src/schema/Account/Account.spec.ts:11:31 - error TS2339: Property 'mockResolvedValue' does not exist on type '<T extends AccountCreateArgs>(args: SelectSubset<T, AccountCreateArgs>) => CheckSelect<T, Prisma__AccountClient<Account>, Prisma__AccountClient<...>>'.
11 prismaMock.account.create.mockResolvedValue(account); Here is my code. //context.mock.ts
import { PrismaClient } from '@prisma/client';
import { MockProxy, mockDeep } from 'jest-mock-extended';
export interface Context {
prisma: PrismaClient;
}
export interface MockContext {
prisma: MockProxy<PrismaClient>;
}
export const createMockContext = (): MockContext => ({
prisma: mockDeep<PrismaClient>(),
}); // Account.spec.ts
import { MockContext, createMockContext } from '../context.mock';
let mockCtx: MockContext;
beforeEach(() => {
mockCtx = createMockContext();
});
describe('GraphQL Account', () => {
test('Should query account', () => {
const account = {
name: 'name',
accountId: 'accountId',
email: 'email@web.com',
};
mockCtx.prisma.account.create.mockResolvedValue(account);
});
}); How can I resolved this issue? Thank you. |
Beta Was this translation helpful? Give feedback.
-
How would you recommend to use mockContext.prisma.user.findFirst<{ include: { posts: true } }>.mockResolvedValue(...)
~~~~~~~~~~~~~~~~~~~~~~~ This however is throwing a type error because apparently Would probably be worth adding a section about relations to the guide. |
Beta Was this translation helpful? Give feedback.
-
Is there an easy way to mock the fluent API with For reference, an abbreviated prisma schema model Graph {
id Int @id @default
variants Variant[] @relation("graph_variants")
}
model Variant {
id Int @id @default
graphId Int
graph Graph @relation("graph_variants", fields: [graphId])
} I need to mock the following call to get a graph's variants via the fluent API. My context is a GraphQL field resolver. In order to avoid the n+1 problem, I'm using the fluent API to resolve the graph's return prisma.graph.findUnique({ where: { id: args.graphId } }).variants() This mock does return the correct data in the test, but produces a Typescript error. I believe this is because I'm not returning all of the // @ts-ignore Ignore the error
prismaSingletonProxy.graph.findUnique.mockReturnValue({
variants: jest.fn().mockResolvedValue([VariantMock]),
});
// Or cast the return value to any
prismaSingletonProxy.graph.findUnique.mockReturnValue({
variants: jest.fn().mockResolvedValue([VariantMock]),
} as any); Is there an easy way around this without having to include an ignore comment or casting the object as any for each of these styles of mock? Typescript Error
|
Beta Was this translation helpful? Give feedback.
-
I'm having issues getting the singleton approach working. I'm using next's rust based compiler. Files: db/prisma.ts import { PrismaClient } from "@prisma/client";
type NodeJsGlobal = typeof globalThis;
interface CustomNodeJsGlobal extends NodeJsGlobal {
prisma: PrismaClient;
}
// Prevent multiple instances of Prisma Client in development
declare const global: CustomNodeJsGlobal;
const prisma = global.prisma || new PrismaClient();
if (process.env.NODE_ENV === "development") global.prisma = prisma;
export default prisma; utils/testing/prisma-mock.ts import prisma from "@db/prisma";
import type { PrismaClient } from "@prisma/client";
import type { DeepMockProxy } from "jest-mock-extended";
import { mockDeep, mockReset } from "jest-mock-extended";
jest.mock("@db/prisma", () => ({
__esModule: true,
default: mockDeep<PrismaClient>(),
}));
beforeEach(() => {
mockReset(prismaMock);
});
export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>; jest.config.ts import nextJest from "next/jest";
import tsconfig from "./tsconfig.json";
/**
* Create Jest module paths from tsconfig paths
*/
const modulePaths = Object.entries(tsconfig.compilerOptions.paths).reduce(
(prev, [alias, path]) => {
return {
...prev,
[`^${alias.replace("*", "(.*)$")}`]: `<rootDir>/${path[0].replace(
"*",
"$1"
)}`,
};
},
{}
);
const createJestConfig = nextJest({
dir: "./",
});
const customJestConfig = {
moduleNameMapper: {
...modulePaths,
},
setupFilesAfterEnv: [
"<rootDir>/setupTests.ts",
"<rootDir>/utils/testing/prisma-mock.ts",
],
collectCoverageFrom: [
"./**/*.ts",
"!jest.config.ts",
"!./db/prisma-seed.ts",
"!setupTests.ts",
],
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig); Every test file now returns the following error:
|
Beta Was this translation helpful? Give feedback.
-
Has anyone gotten the unit testing guide to work with Jest 28+ and jest-mock-extended > 2.0.4? I know you need at least v2.0.6 of jest-mock-extended to use Jest 28. Currently, I am running into several problems using the latest versions of both libraries. From the Slack channel: I am following the example here https://www.prisma.io/docs/guides/testing/unit-testing#singleton, but when running the tests I am getting I have now come to realize that the error is happening in node_modules/jest-mock-extended/lib/Mock.js on line 56:
Hmm, I just tried to install the same version of jest-mock-extended used in the docs but it seems it does not support version 28 of Jest:
|
Beta Was this translation helpful? Give feedback.
-
I'm following the singleton approach described in your guide and keep getting |
Beta Was this translation helpful? Give feedback.
-
Following the singleton example (found here: https://www.prisma.io/docs/guides/testing/unit-testing), I tried to put the function I was testing in the same file as the test itself in order to make a concise working example for colleagues. i.e: // function I'm testing
import prisma from ''../lib/prisma'';
interface CreateUser {
name: string
profile_picture: string
created_by: string
updated_by: string
}
export async function createUser(user: CreateUser) {
return await prisma.user.create({
data: user,
})
}
// Test
import { prismaMock } from './../singleton'
test('should create new user ', async () => {
const user = {
id: 1,
name: 'Rich',
email: 'hello@prisma.io',
acceptTermsAndConditions: true,
}
prismaMock.user.create.mockResolvedValue(user)
await expect(createUser(user)).resolves.toEqual({
id: 1,
name: 'Rich',
email: 'hello@prisma.io',
acceptTermsAndConditions: true,
})
}) This left me pulling my hair out for a while as my database was creating records of beforeEach(() => {
mockReset(prismaMock)
})
afterAll(() => {
mockReset(prismaMock)
}) After moving the function I was testing to a separate file, these side effects disappeared as I would have hoped. If anyone has a good explanation for why this happened, would be awesome (beyond the obvious, "direct import of your client in the test file overwrote the mock client in the test file, but not in a separate file" - again, looking for a 'why' here) |
Beta Was this translation helpful? Give feedback.
-
Someone, |
Beta Was this translation helpful? Give feedback.
-
Are Prisma unit tests really required if you've got a function whose only job is to use the Prisma Client? If you're using a data access layer, the majority (if not all) of these functions' jobs will be to call the respective ORM layer. E.g. This createTweet function just returns the response from the Prisma Client: export class TweetsRepository {
constructor(private prisma: PrismaService) {}
async createTweet(params: { data: Prisma.TweetCreateInput }): Promise<Tweet> {
const { data } = params;
return this.prisma.tweet.create({ data });
}
} Is there any value in unit testing this? This would just be testing to see if the Prisma Client creates Tweets. I can understand the value in unit testing if the function has some extra logic outside of the Prisma client. E.g. Continuing from the above example, if I wanted to throw an error if the characters of the Tweet exceeded a specified limit: export class TweetsRepository {
constructor(private prisma: PrismaService) {}
async createTweet(params: { data: Prisma.TweetCreateInput }): Promise<Tweet> {
const { data } = params;
if (data.content.length > 280) {
throw new Error(`Tweet too long`);
}
return this.prisma.tweet.create({ data });
}
} Adding a unit test for this function makes sense - you want to test the scenario where tweets under and over the character limit are handled properly. I'm interested to hear some perspectives on:
|
Beta Was this translation helpful? Give feedback.
-
Hi, I'm using error TS2339: Property 'mockResolvedValue' does not exist on type 'CalledWithMock<PrismaPromise<banks[]>, [args?: { select?: banksSelect | null | undefined; include?: banksInclude | This is form my "@types/jest": "^27.5.2",
"jest": "^27.5.1",
"jest-mock-extended": "2.0.4",
"ts-jest": "^27.1.5", This is my code: import { PrismaClient } from '@prisma/client';
import {jest, beforeEach} from '@jest/globals';
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended';
import prisma from '../src/services/prisma';
jest.mock('../src/services/prisma', () => ({
__esModule: true,
default: mockDeep<PrismaClient>(),
}));
beforeEach(() => {
mockReset(prismaMock);
});
export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>;
import {beforeAll, describe, it} from '@jest/globals';
import {prismaMock} from "../singleton";
describe('', () => {
it('', () => {
beforeAll(() => {
prismaMock.banks.findMany.mockResolvedValue([])
^^^^^^^^^^^^^^^
});
});
}); Any advice? |
Beta Was this translation helpful? Give feedback.
-
If anyone else stumbles here, I didn't find a satisfying solution, so I created my own: https://github.com/morintd/prismock. (Also asked in a discussion) |
Beta Was this translation helpful? Give feedback.
-
First of all, sorry for bumping this thread, but after some backbreaking digging to understand what was happening, I could mock my This solution is based on a structure like the following, and it requires
// src/clients/prisma.ts
import { PrismaClient } from '@prisma/client';
export const prisma = new PrismaClient({
db: {
url: process.env.DATABASE_URL,
},
}); // src/clients/__mocks__/prisma.ts
import { PrismaClient } from '@prisma/client';
import { mockReset, mockDeep } from 'jest-mock-extended';
export const prismaMock = mockDeep<PrismaClient>();
jest.mock('../prisma', () => ({
prisma: prismaMock,
}));
beforeEach(() => {
mockReset(prismaMock);
});
export const prisma = prismaMock; // src/user-action.ts
import { prisma } from './clients/prisma';
export async function getUsers() {
return prisma.user.findAll();
} // tests/user-actions.test.ts
import { getUsers } from '../src/user-actions';
import { prisma } from '../src/clients/prisma';
jest.mock('../src/clients/prisma');
const prismaMocked = jest.mocked(prisma);
test('getUsers: returns all users', async () => {
// setup
prismaMocked.user.findAll.mockResolvedValue(<mocked-value-here>);
// test
const users = await getUsers();
// assert
expect(users).toStrictEqual(<expectation>);
}); This should be enough to make |
Beta Was this translation helpful? Give feedback.
-
I can't get the example with singleton and without context to work. It only works if I place the |
Beta Was this translation helpful? Give feedback.
-
Any recommendations on mocking |
Beta Was this translation helpful? Give feedback.
-
Sorry for being asking such a stupid quest but here goes my problem
When running on a normal database the results look something like these:
But when using a mock data:
the return don't query the cdvisao. other mocked data work fine, but the ones with where clause simply don't filter. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
This is a space for community members to provide feedback on and participate in discussions surrounding our unit testing guide.
Bear in mind that this is a first iteration and as such doesnt cover every known use case. Moving forward we would like to cover as much ground as possible with these guides.
Some handy stuff we would like to know:
And of course any other feedback you might have is most welcome 😀
Beta Was this translation helpful? Give feedback.
All reactions