I try mock vue-router in the test.
I have a composable file with RouterLink.useLink
const link = isRouterLink.value ? RouterLink.useLink(props as UseLinkOptions) : undefined;
console.log(link?.route.value.href)
In the test, I create a mock router
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: { template: 'Home' }
},
{
path: '/about',
component: { template: 'About' }
}
]
});
vitest
const wrapper = mount(Link), {
propsData: { to: '/' },
global: {
plugins: [router]
}
});
Then test in failed, error
TypeError: Cannot read properties of undefined (reading 'resolve')
because link?.route does not have value properties
console.log(link?.route.value) // => 'undefined'
but in the browser or cypress testing, all is good, there I have
console.log(link?.route.value.href) // => '/'
And all properties in link.route does not have a value in vitest.
How can I resolve this problem?
Related
I'm want to unit test Next.js API route with Prisma in JavaScript. Unfortunately, the Prisma's unit testing guide is written for Typescript.
I have jest.config.js which will setup the mock in jest.setup.js
const nextJest = require("next/jest");
const createJestConfig = nextJest({
dir: "./",
});
const config = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
moduleDirectories: ["node_modules", "<rootDir>/"],
moduleNameMapper: {
"#/(.*)$": "<rootDir>/$1",
},
};
module.exports = createJestConfig(config);
and this is how I configured the mock in jest.setup.js
import prisma from "#/utils/client";
jest.mock("#/utils/client", () => ({
__esModule: true,
default: {
user: {
findMany: jest.fn(),
},
// ... and each and everyone of the entities
},
}));
export const prismaMock = prisma;
and the following test case passed
describe("Calculator", () => {
it("renders a calculator", async () => {
await prismaMock.user.findMany.mockResolvedValue(["abc]);
const { req, res } = createMocks();
await handler(req, res);
expect(res._getStatusCode()).toBe(200);
expect(res._getData()).toBe('["abc"]');
});
});
With this approach, I have to mock each and everyone of the models and function in jest.setup.js. Is there a way to mock all the models and functions automatically? Is there a similar JavaScript library which provides mockDeep from jest-mock-extended?
While trying to upgrade babel to v7 in an existing test setup with Jest and Enzyme, I have encountered a problem where Web API File is empty. Although it responds to methods like myFile.name.
Packages used:
babel => 7.6.4
jest => 24.9.0
babel-jest => 24.9.0
Not really an expert with babel, but this is my config
Babe config
const env = process.env.NODE_ENV;
const isProd = () => env === 'production';
const isDev = () => env === 'development';
const isTest = () => env === 'test';
const babelPresetEnvOptions = () => {
const options = {};
if (isTest()) {
options.targets = { node: 'current' };
} else {
// Disable polyfill transforms
options.useBuiltIns = false;
// Do not transform modules to CommonJS
options.modules = false;
}
if (isProd()) {
options.forceAllTransforms = true;
}
return options;
};
const presets = [
[require.resolve('#babel/preset-env'), babelPresetEnvOptions()],
[require.resolve('#babel/preset-react'), { development: isDev() }],
];
const plugins = [
[require.resolve('#babel/plugin-proposal-decorators'), { legacy: true }],
[require.resolve('#babel/plugin-proposal-class-properties'), { loose: true }],
require.resolve('#babel/plugin-proposal-object-rest-spread'),
require.resolve('#babel/plugin-transform-react-jsx'),
require.resolve('#babel/plugin-transform-runtime'),
];
if (isTest()) {
// Compiles import() to a deferred require()
plugins.push(require.resolve('babel-plugin-dynamic-import-node'));
} else {
// Adds syntax support for import()
plugins.push(require.resolve('#babel/plugin-syntax-dynamic-import'));
}
module.exports = api => {
api.assertVersion('^7.6');
return {
presets,
plugins,
};
};
Jest setup
"jest": {
"rootDir": "./webpack",
"setupFiles": [
"<rootDir>/test/jestsetup.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"moduleNameMapper": {
"^.+\\.(css|scss)$": "identity-obj-proxy"
},
"transform": {
"^.+\\.(js|jsx)?$": "babel-jest"
}
},
Problem:
When I try to initiate a file object
const lastModified = 1511256180536;
const myImageFile = new File([''], 'pixel.gif', { type: 'image/gif', lastModified });
console.log(myImageFile); // Also results in => File {}
console.log(imageFile.name); // return 'pixel.gif'
The test snapshot fails as shown below, which I can't explain why.
- file={
- File {
- Symbol(impl): FileImpl {
- "_buffer": Object {
- "data": Array [],
- "type": "Buffer",
- },
- "isClosed": false,
- "lastModified": 1511256180536,
- "name": "pixel.gif",
- "type": "image/gif",
- Symbol(wrapper): [Circular],
- },
- }
- }
+ file={File {}}
Even a hint on this would be great.
Babel debug
#babel/preset-env: `DEBUG` option
Using targets:
{
"node": "12.11"
}
Using modules transform: auto
Using plugins:
syntax-async-generators { "node":"12.11" }
syntax-object-rest-spread { "node":"12.11" }
syntax-json-strings { "node":"12.11" }
syntax-optional-catch-binding { "node":"12.11" }
transform-modules-commonjs { "node":"12.11" }
proposal-dynamic-import { "node":"12.11" }
Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
I'm having trouble getting my configuration right for this. I have a NextJS setup with next-css and I'm trying to add react-svg-loader to the configuration:
next.config.js:
const withCSS = require("#zeit/next-css");
module.exports = withCSS({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[local]__[hash:base64:4]"
},
webpack(config, options) {
const { dev, isServer } = options;
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: "react-svg-loader",
options: {
jsx: true // true outputs JSX tags
}
}
]
});
return config;
}
});
The svgs will still fail to load:
{ Error: (client) ./svgs/pencil.svg 10:9 Module parse failed:
Unexpected token (10:9) You may need an appropriate loader to handle
this file type.
Looks like my config above doesn't work but I can't quite figure out why.
I'm starting out with vue and nuxt, I have a project using vuetify and I'm trying to modify the carousel component to dynamically load images from the static folder. So far I've come up with:
<template>
<v-carousel>
<v-carousel-item v-for="(item,i) in items" :key="i" :src="item.src"></v-carousel-item>
</v-carousel>
</template>
<script>
function getImagePaths() {
var glob = require("glob");
var options = {
cwd: "./static"
};
var fileNames = glob.sync("*", options);
var items = [];
fileNames.forEach(fileName =>
items.push({
'src': '/'+fileName
})
);
return items;
}
export default {
data() {
return {items :getImagePaths()};
}
};
</script>
When I test this I see:
ERROR in ./node_modules/fs.realpath/index.js
Module not found: Error: Can't resolve 'fs' in '....\node_modules\fs.realpath'
ERROR in ./node_modules/fs.realpath/old.js
Module not found: Error: Can't resolve 'fs' in ....\node_modules\fs.realpath'
ERROR in ./node_modules/glob/glob.js
Module not found: Error: Can't resolve 'fs' in '....\node_modules\glob'
ERROR in ./node_modules/glob/sync.js
Module not found: Error: Can't resolve 'fs' in '.....\node_modules\glob'
googling this I see a bunch of references like https://github.com/webpack-contrib/css-loader/issues/447.
These suggest that you have to midify the webpack config file with something like:
node: {
fs: 'empty'
}
I know very little about webpack. I found https://nuxtjs.org/faq/extend-webpack/ , but am not sure how to modify the webpack config file in this case.
How do I do this?
You can't use NodeJs specific module on browser.
To solve your issue, you can create an API using Nuxt server middleware. The code below, inspired by https://github.com/nuxt-community/express-template.
Create a file, index.js in api/index.js. Then fill it with:
const express = require('express')
// Create express instance
const app = express()
// Require API routes
const carousel = require('./routes/carousel')
// Import API Routes
app.use(carousel)
// Export the server middleware
module.exports = {
path: '/api',
handler: app
}
Create carousel.js in api/routes/carousel.js. Then fill it with:
const { Router } = require('express')
const glob = require('glob')
const router = Router()
router.get('/carousel/images', async function (req, res) {
const options = {
cwd: './static'
}
const filenames = glob.sync('*', options)
let items = [];
filenames.forEach(filename =>
items.push({
'src': '/'+filename
})
);
return res.json({ data: items })
})
module.exports = router
Register your server middleware in nuxt.config.js
module.exports = {
build: {
...
},
serverMiddleware: [
'~/api/index.js'
]
}
Call the api in your page / component. I assume you're using Axios here (axios-module).
<script>
export default {
async asyncData ({ $axios }) {
const images = (await $axios.$get('/api/carousel/images')).data
return { images }
}
}
</script>
I know this is an old question, but it may be helpful for someone to disable fs in their browser.
Like this:
nuxt.config.js
build: {
extend (config, { isDev, isClient }) {
config.node= {
fs: 'empty'
}
// ....
}
},
Add this in your nuxt-config.js:
build: { extend (config, { isDev, isClient }) {
config.node = {
fs: 'empty'
}
// ....
}},
I am developing a web app using the MEAN stack (no Mongo for now)
I am trying to pass the name of a file on the server using a query paramerer, the error happens when i get :
"localhost:8080/api/result?filename=for-debug-file-name"
It is working well if I remove the console.log() right below
But when I get the query parameter it gets me the "Error: No default engine was specified and no extension was provided”.
(This route correspond to api/result)
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
console.log(req.query('filename')); // ERROR
res.status(200).json({ "json-test": 42 });
})
module.exports = router;
Here are my angular routes :
const appRoutes: Routes = [
{
path: 'result',
component: ResultComponent,
},
{
path: 'upload',
component: UploaderComponent,
},
{
path: '',
redirectTo: '/upload',
pathMatch: 'full'
}];
And here is my ResultComponent.ts :
ngOnInit() {
this.getParsedDocumentData('for-debug-file-name');
}
getParsedDocumentData(fileName: string): Observable<string[]> {
let params = new URLSearchParams();
params.append('filename', fileName);
let options = new RequestOptions({ params: params });
return this.http.get('http://localhost:8080/api/result/', options)
.map(res => res.json())
.catch(this.handleError);
}
private handleError (error: any) {
return Observable.throw(error);
}
I would really appreciate your help as I have been stuck for 4 hours.
Thanks.
query method in request object does not exists. Instead use query property to access filename parameter.
console.log(req.query.filename);
Reference