#angular #unit-testing #jasmine #karma-jasmine #karma-runner
Вопрос:
Я новичок в написании угловых тестовых случаев с использованием Jasmine, я пытаюсь вызвать функцию getRoleModulePermissionById(event,id)
, manage-permissions.component.spec.ts
которая находится внутри manage-permissions.component.ts
Компонент Управления разрешениями:
getRoleModulePermissionById(event,id) {
this. moduleNameStr = event.target.innerText
console.log("this. moduleNameStr",this. moduleNameStr)
console.log("id-----------------",id,);
this.moduleId=id;
this.roleService.getRoleModulePermission(id).subscribe(
(response) => {
this.isShow = true;
this.getHide = true;
this.roleList = response;
console.log('inside get ' JSON.stringify(this.roleList))
},
(httpErrorRes) => {
alert(constants.roleModuleNotFound);
}
);
this.prepareBreadcrumb();
}
Спецификация управления разрешениями:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { constants } from '../../../shared/static/constants';
import { ModuleServiceService } from '../../services/module-service.service';
import { ManagePermissionsComponent } from './manage-permissions.component';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
// mock the service
class MockModuleservice extends ModuleServiceService {
// mock everything used by the component
};
describe('ManagePermissionsComponent', () => {
let component: ManagePermissionsComponent;
let fixture: ComponentFixture<ManagePermissionsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule,HttpClientTestingModule],
declarations: [ ManagePermissionsComponent ],
providers: [{
provide: ModuleServiceService ,
useClass: MockModuleservice
}]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ManagePermissionsComponent);
component = fixture.debugElement.componentInstance;
fixture.detectChanges();
});
it('should create manage-permission', () => {
expect(component).toBeTruthy();
});
it('should able to getRoleModulePermissionById', () => {
component.getRoleModulePermissionById(null,1);
expect(component).toBeTruthy();
})
});
Я не в состоянии понять, как вызвать функцию,так как экземпляр ManagePermissionsComponent
уже был создан beforEach()
. Я пытаюсь подготовить отчет о покрытии кода,поэтому я хочу охватить все строки кода внутри функции getRoleModulePermissionById
, но не могу этого сделать
Пожалуйста, поправьте меня, если я делаю что-то не так, а также предоставьте мне руководство по лучшей практике Жасмин.
Karma.conf.js файл
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, '../../coverage'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};
Комментарии:
1. component.getRoleModulePermissionById(null,1); это должно вызвать эту функцию. С какой проблемой вы столкнулись?
Ответ №1:
Вам нужно сделать пару вещей, чтобы строки были отражены в отчете.
- Закрывайте строки, которых нет в функции subscribe() .
- Закройте строки, которые находятся в функции subscribe ().
Пожалуйста, сделайте следующее:
@Injectable()
class MockRoleService extends RoleService {
getRoleModulePermission(): any {
const mockData = {} // Fill the type of response here
return of(mockData); // Import 'of' from 'rxjs'
}
}
// Add this in the providers:
// Add a service mocker here;
let roleService: RoleService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule,HttpClientTestingModule],
declarations: [ ManagePermissionsComponent ],
providers: [
{
provide: ModuleServiceService ,
useClass: MockModuleservice
},
{
provide: RoleService ,
useClass: MockRoleService
}
]
})
.compileComponents();
});
roleService = TestBed.get(RoleService); <-- this line is important to mock API Failure scenario
// Now the test cases:
// HTTP Success scenarios
it('should run the #getRoleModulePermissionById() success response of subscribe', () => {
spyOn(component, 'getRoleModulePermissionById').and.callThrough();
const event = {
target: {
innerText: 'someInnerText'
}
};
component.getRoleModulePermissionById(event, 'someId');
expect(component.getRoleModulePermissionById).toHaveBeenCalled();
});
// HTTP Failure error scenario
it('should run #getRoleModulePermissionById() method, API-Failure scenario', () => {
const errorResponse = { status: 500 };
spyOn(roleService, 'getRoleModulePermission').and.returnValue(throwError(errorResponse));
spyOn(component, 'getRoleModulePermissionById').and.callThrough();
const event = {
target: {
innerText: 'someInnerText'
}
};
component.getRoleModulePermissionById(event, 'someId');
expect(component.getRoleModulePermissionById).toHaveBeenCalled();
})
Эти 2 тестовых примера должны идеально подходить для обоих сценариев.
Комментарии:
1. Срикар, спасибо за ответ. Я попробовал ваше решение, но теперь отчет о покрытии кода сам по себе не генерируется. Когда я выполняю сгенерированный отчет о покрытии кода отмены действия, я не могу понять, что пошло не так
2. Эти тестовые случаи не вызывают проблем с созданием отчета. Происходит что-то еще. Открывается ли браузер karma? Если да, вы получаете какие-либо ошибки консоли? Если это так, вставьте их иначе, это более серьезная проблема, и мы должны увидеть, что происходит. Попробуйте добавить весь код в stackblitz или что-то в этом роде, и мы посмотрим, сможем ли мы воспроизвести проблему там. Тогда мы сможем действовать соответственно
Ответ №2:
Вам нужно правильно имитировать службу ролей и вернуть макет ответа в тестовом примере, чтобы протестировать блок подписки, в jasmine именно так мы создаем заглушку:
const roleServiceStub = jasmine.createSpyObj('RoleService', ['getRoleModulePermission']);
и тогда вам нужно будет предоставить эту услугу вашему тестовому угловому модулю, вот так:
{ provide: RoleService, useValue: roleServiceStub }
Вот полный тест для блока подписки и блока ошибок:
describe('ManagePermissionsComponent', () => {
let component: ManagePermissionsComponent;
let fixture: ComponentFixture<ManagePermissionsComponent>;
const roleServiceStub = jasmine.createSpyObj('RoleService', ['getRoleModulePermission']);
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule, HttpClientTestingModule],
declarations: [ManagePermissionsComponent],
providers: [{
provide: ModuleServiceService,
useClass: MockModuleservice
}, { provide: RoleService, useValue: roleServiceStub },]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ManagePermissionsComponent);
component = fixture.debugElement.componentInstance;
fixture.detectChanges();
});
it('should create manage-permission', () => {
expect(component).toBeTruthy();
});
it('should able to getRoleModulePermissionById', () => {
const mockRoleResponse = {
}; // Keep is as your response
roleServiceStub.getRoleModulePermission.and.returnValue(of(mockRoleResponse));
component.getRoleModulePermissionById(null, 1);
expect(component.roleList).toBeTruthy();
// Write other assertion based on your mock respone
});
it('should handle error', () => {
const mockRoleResponse = {
}; // Keep is as your response
spyOn(window, 'alert');
roleServiceStub.getRoleModulePermission.and.returnValue(throwError({ error: 'some error'));
component.getRoleModulePermissionById(null, 1);
expect(window.alert).toHaveBeenCalled();
});
});
Комментарии:
1. Райтеш, спасибо за ответ. Я попробовал ваше решение, но теперь отчет о покрытии кода сам по себе не генерируется. Когда я выполняю отчет о покрытии кода отмены действия, созданный, я не в состоянии понять, что пошло не так.
2. Прошли ли все тестовые случаи? Покажите мне ваш файл karma.conf.
3. Пожалуйста, ознакомьтесь с моими изменениями и любезно предложите мне решение.
4. Не могли бы вы, пожалуйста, открыть дискуссионный чат, у меня много вопросов по модульному тестированию angular?
5. Похоже, у вас не настроены HTML — отчеты.