How to fix "Jest encountered an unexpected token" - unit-testing

I wrote following unit test case
import { shallowMount } from '#vue/test-utils'
import OverviewKB from '#/components/knowledgebase/OverviewKB.vue'
describe('Mounted OverviewKB', () => {
const wrapper = shallowMount(OverviewKB);
test('does a wrapper exist', () => {
expect(wrapper.exists()).toBe(true)
})
})
Following error occurred.

Related

Mock objection model dependecy in NestJs with Jest

I'm trying to make unit test with nestjs and objection. The problem I have is that I can't mock the "User" Model that is injected with the decorator "#InjectModel". I searched a lot to find a solution but I didn't find anything.
users.service.ts
import { HttpException, HttpStatus, Inject, Injectable } from '#nestjs/common';
import { CreateUserDto } from './create-user.dto';
import { User } from 'src/app.models';
import { InjectModel } from 'nestjs-objection';
#Injectable()
export class UsersService {
constructor(
#InjectModel(User) private readonly userModel: typeof User,
) {}
async create(createUserDto: CreateUserDto) {
try {
const users = await this.userModel.query().insert(createUserDto);
return users
} catch (err) {
console.log(err)
throw new HttpException(err, HttpStatus.BAD_REQUEST);
}
}
}
users.service.spec.ts
import { Test, TestingModule } from "#nestjs/testing";
import { UsersService } from "../src/users/users.service";
import { CreateUserDto } from "src/users/create-user.dto";
import { User } from "../src/app.models";
import { getObjectionModelToken } from 'nestjs-objection';
describe('userService', () => {
let userService: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{
provide: User,
useValue: {}
},
],
}).compile();
userService = module.get<UsersService>(UsersService);
});
it('Should be defined', () => {
expect(userService).toBeDefined();
});
it('Should add pin to a created user', async () => {
const createUserDTO: CreateUserDto = {
email: 'mockEmail#mock.com',
userName: 'user'
}
const res = await userService.create(createUserDTO)
expect(res).toHaveProperty('pin')
});
I tried to use import { getObjectionModelToken } from 'nestjs-objection'; inside provider like this:
providers: [
UsersService,
{
provide: getObjectionModelToken(User),
useValue: {}
},
],
I got this error
It asks for a "connection" but I don't know what to put on it.
I suppose "getObjectionModelToken" is the function to mock the "InjectModel". When I pass an empty string
I got this error:
● Test suite failed to run
Cannot find module 'src/app.models' from '../src/users/users.service.ts'
Require stack:
C:/nestjs-project/nestjs-knex/src/users/users.service.ts
users.repository.spec.ts
1 | import { HttpException, HttpStatus, Inject, Injectable } from '#nestjs/common';
2 | import { CreateUserDto } from './create-user.dto';
> 3 | import { User } from 'src/app.models';
| ^
4 | import {
5 | InjectModel,
6 | synchronize,
at Resolver._throwModNotFoundError (../node_modules/jest-resolve/build/resolver.js:491:11)
at Object.<anonymous> (../src/users/users.service.ts:3:1)
If I change the path it breaks the correct functionality of the app
That looks like an error from jest not understanding what src/* imports are. Either use relative imports rather than absolute (e.g. use import { User } from '../app.models') or tell jest how to resolve src/* imports via the moduleNameMapper in your jest.config.js or package.json
{
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/path/to/src/$1"
}
}
I think based on the error your /path/to/src should be ../src but I'm not 100% sure, so make sure you set that correctly.

vue3 vitest mock axios can't read 'then'

I have the function in the Races.vue file, the front end is working fine but not testing
getRaces: function () {
axios.get(URL)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
this.errored = true;
})
.finally(() => {
this.loading = false;
})
}
And when I try to test it, after adding vi.mock part, will give "TypeError: Cannot read properties of undefined (reading 'then')" error
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { shallowMount, mount, flushPromises } from '#vue/test-utils'
import Races from '../Races.vue'
import axios from 'axios'
vi.mock("axios", () => {
return {
default: {
get: vi.fn(),
},
};
});
Any idea on how to solve this? Thank you so much

vuejs unit test a component which has a child component

I want to test a TheLogin.vue component that has a child BaseInput.vue component. I tried the code below and also shallowMount but I keep getting the error below.
TheLogin.vue
<template>
<section>
<legend>
Hello Login
</legend>
<BaseInput id="userName"></BaseInput>
</section>
</template>
export default {
name: 'TheLogin',
data() {
return {
userName: null
}
}
}
TheLogin.spec.js
import TheLogin from '#/pages/login/TheLogin.vue';
import BaseInput from '#/components/ui/BaseInput.vue';
import { createLocalVue, mount } from '#vue/test-utils';
describe('TheLogin.vue', () => {
const localVue = createLocalVue();
localVue.use(BaseInput); // no luck
it('renders the title', () => {
const wrapper = mount(TheLogin, {
localVue,
// stubs: {BaseInput: true // no luck either
// stubs: ['base-input'] // no luck again
});
expect(wrapper.find('legend').text()).toEqual(
'Hello Login'
);
});
I import my base components in a separate file which I import into my main.js
import Vue from 'vue';
const components = {
BaseInput: () => import('#/components/ui/BaseInput.vue'),
BaseButton: () => import('#/components/ui/BaseButton.vue'),
//et cetera
};
Object.entries(components).forEach(([name, component]) =>
Vue.component(name, component)
);
The error I'm getting is:
TypeError: Cannot read property 'userName' of undefined
UPDATE
Turned out it was Vuelidate causing the error (the code above was not complete). I also had in my script:
validations: {
userName: {
required,
minLength: minLength(4)
},
password: {
required,
minLength: minLength(4)
}
}
I solved it by adding in my test:
import Vuelidate from 'vuelidate';
import Vue from 'vue';
Vue.use(Vuelidate);
Have you tried to shallow mount the component without using localVue and setting BaseInput as a stub?
Something like:
import TheLogin from '#/pages/login/TheLogin.vue';
import { shallowMount } from '#vue/test-utils';
describe('TheLogin.vue', () => {
it('renders the title', () => {
const wrapper = shallowMount(TheLogin, {
stubs: { BaseInput: true }
});
expect(wrapper.find('legend').text()).toEqual(
'Hello Login'
);
});
});

Error when setting base test providers into several unit tests

I use Angular2 RC1 and I have several unit tests regarding different components with the following structure:
import {provide} from '#angular/core';
import {
TestComponentBuilder
} from '#angular/compiler/testing';
import {
beforeEach,
ddescribe,
xdescribe,
describe,
expect,
iit,
inject,
injectAsync,
async,
beforeEachProviders,
setBaseTestProviders,
it,
xit
} from '#angular/core/testing';
import {
TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
} from '#angular/platform-browser-dynamic/testing/browser';
describe('Test component 1', () => {
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
it('should something',
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
var updateService = new UpdateService();
tcb.overrideProviders(ShapeCircleLayerComponent, [
provide(UpdateService, { useValue: updateService })
])
.createAsync(Component1).then((componentFixture) => {
(...)
});
});
});
});
Each test works if run alone but when I run them at the same time within Karma, I get the following error:
Chrome 50.0.2661 (Linux 0.0.0) Test for shape circle layer encountered a declaration exception FAILED
Error: Cannot set /home/(...)/my-project providers because it has already been called
at new BaseException (/home/(...)/my-project/node_modules/#angular/core/src/facade/exceptions.js:17:23)
at Object.setBaseTestProviders (/home/(...)/my-project/node_modules/#angular/core/testing/test_injector.js:74:15)
```
It seems that several tests that set base test providers (TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS) can't be executed at the same time.
Does anyone have this problem? Thanks very much!
As #teleaziz suggested, you should do this only once. So such processing needs to be moved into the karma-test-shim.js file. Here is a sample:
System.import('#angular/platform-browser/src/browser/browser_adapter')
.then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
.then(function() {
return Promise.all([
System.import('#angular/core/testing'),
System.import('#angular/platform-browser-dynamic/testing/browser')
]);
})
.then(function(modules) {
var testing = modules[0];
var testingBrowser = modules[1];
testing.setBaseTestProviders(
testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
})
.then(function() { return Promise.all(resolveTestFiles()); })
.then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });

How to properly unit test an Angular2 http service with the MockBackend?

When running npm test I get this error:
src/client/app/shared/services/scientist.service.spec.ts(20,7): error TS2345: Argument of type 'Function' is not assignable to parameter of type '(done: () => void) => void'.
Type 'Function' provides no match for the signature '(done: () => void): void'
I'am using this angular2 seed: https://github.com/mgechev/angular2-seed and I changed the scientist name-list service to get the data from http, based on this blog: http://chariotsolutions.com/blog/post/testing-http-services-angular-2-jasmine/.
So I created my Scientist class with asScientist and asScientists methods that create instances from json.
scientist.service.ts:
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Scientist} from './scientist';
#Injectable()
export class ScientistService {
private url = 'http://path/to/scientists/';
constructor(private http:Http) {
}
get():Observable<Scientist[]> {
return this.http.get(this.url)
.map((res:Response) => {
return Scientist.asScientists(res.json());
});
}
}
scientist.service.spec.ts:
import {provide} from 'angular2/core';
import {beforeEachProviders, inject} from 'angular2/testing';
import {XHRBackend, ResponseOptions, Response} from 'angular2/http';
import {MockBackend, MockConnection} from 'angular2/src/http/backends/mock_backend';
import {Scientist} from './scientist';
import {ScientistService} from './scientist.service.ts';
export function main() {
describe('Scientist Service', () => {
beforeEachProviders(() => {
return [HTTP_PROVIDERS, provide(XHRBackend, {useClass: MockBackend}), ScientistService];
});
it('should get the list of scientists',
// ##### Line below causes the error #####
inject([XHRBackend, ScientistService], (mockBackend:MockBackend, scientistService:ScientistService) => {
mockBackend.connections.subscribe(
(connection:MockConnection) => {
// Haven't changed these yet since I want to make the test pass first
connection.mockRespond(new Response(
new ResponseOptions({
body: [
{
id: 26,
contentRendered: '<p><b>Hi there</b></p>',
contentMarkdown: '*Hi there*'
}]
}
)));
});
scientistService.get().subscribe((scientists:Scientist[]) => {
expect(scientists.length).toBe(1);
//expect(scientists[0].id).toBe(26);
//expect(data[0].contentMarkdown).toBe('*Hi there*');
},
(error:any) => {
// we can call a failure case here...
fail(error);
});
}));
});
}
It seems to be a syntax error but not a very obvious one, so any kind of help will be appreciated!
Maybe you need import all test methods from the angular2/testing module.
Like this:
import {it, beforeEachProviders, describe, expect, beforeEach, inject, injectAsync} from 'angular2/testing';
Because in your code I saw you just import "beforeEachProviders" and "inject".