Вызов функции, присутствующей внутри компонента, из файла spec.ts в angular 8

#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:

Вам нужно сделать пару вещей, чтобы строки были отражены в отчете.

  1. Закрывайте строки, которых нет в функции subscribe() .
  2. Закройте строки, которые находятся в функции 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 — отчеты.