Как вручную создать файлы spec.ts для компонентов?

#angular #typescript #unit-testing

#angular #typescript #модульное тестирование

Вопрос:

Как говорится в вопросах, я хочу создать файлы spec.ts вручную, поскольку разработчики отключили автоматическую генерацию при создании компонентов. Я скопировал один файл spec.ts, который у них был, в каждый отдельный компонент, поэтому он выглядит так, за исключением того, что имя компонента отличается для каждого из них:

 import { ComponentFixture, TestBed } from '@angular/core/testing';

import { NavMenuComponent } from './nav-menu.component';

describe('NavMenuComponent', () => {
  let component: NavMenuComponent;
  let fixture: ComponentFixture<NavMenuComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ NavMenuComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NavMenuComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
  

Тем не менее, я выполнил «тест запуска npm», и он не удался практически для всех. Я думаю, это потому, что есть другие шаги, которые я должен выполнить, помимо простого создания файла spec.ts и ввода этого кода? Я пытался решить этот вопрос, рассмотрев другие связанные вопросы, и кажется, что я импортирую что-то, чего не существует, но я не знаю, как исправить эту проблему. Сбой при тестировании запуска npm очень длинный:

 Chrome 85.0.4183.121 (Mac OS 10.15.7) SelectiveComponent should create FAILED
NullInjectorError: R3InjectorError(DynamicTestModule)[SearchService -> HttpClient -> HttpClient]: 
  NullInjectorError: No provider for HttpClient!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'SearchService', 'HttpClient', 'HttpClient' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[SearchService -> HttpClient -> HttpClient]: 
  NullInjectorError: No provider for HttpClient!
    at NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:915:1)
    at R3Injector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11076:1)
    at R3Injector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11076:1)
    at injectInjectorOnly (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:801:1)
    at ɵɵinject (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:805:1)
    at Object.SearchService_Factory [as factory] (ng:///SearchService/ɵfac.js:5:41)
    at R3Injector.hydrate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11243:1)
    at R3Injector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11065:1)
    at NgModuleRef$1.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:24193:1)
    at Object.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:22094:1)
Error: Expected undefined to be truthy.
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/modules/dashboard/search-selective/selective.component.spec.ts:23:23)
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:365:1)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:305:1)
  

Любая информация будет с благодарностью принята!

Комментарии:

1. Есть ли что-то вроде контрольного списка, который мне нужно сделать, чтобы вручную создать эти файлы spec.ts? Я ничего не мог найти в Интернете

Ответ №1:

Ошибка подразумевает, что у вас NavMenuComponent есть SearchService служба, которая вводит в HttpClient нее службу, введенную в нее.

Вы можете имитировать зависимость с помощью jasmine. При тестировании компонентов я обычно предпочитаю издеваться над прямыми зависимостями. При тестировании компонента вы можете имитировать любой из SearchService вызовов.

 describe('NavMenuComponent', () => {
  let component: NavMenuComponent;
  let fixture: ComponentFixture<NavMenuComponent>;
  
  // create a mock of the http client
  // the second param will be a list of functions your service has to offer
  let mockSearchService = jasmine.createSpyObj('searchService', ['search']);

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ NavMenuComponent ],
      providers: [
        // provide your obj in place of the actual SearchService
        {provide: SearchService, useValue: mockSearchService}     
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NavMenuComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
  

Комментарии:

1. Извините, это была опечатка. Я исправил это. Это должно было быть «SearchService», потому что это прямая зависимость от вашего NavMenuComponent.