проблема с тестом ng при тестировании компонента

#angular #typescript #testing #karma-jasmine

Вопрос:

У меня есть следующая ошибка, когда я тестирую компонент на Angular 12:

Ошибка: Неожиданное значение «ParamDecoratorFactory», импортированное модулем «DynamicTestModule». Пожалуйста, добавьте аннотацию @NgModule. при проверке семантики Ngmoduledef (http://localhost:9876/karma_webpack/vendor.js:85197:19) в http://localhost:9876/karma_webpack/vendor.js:85208:9 в Array.forEach () в verifySemanticsOfNgModuleDef (http://localhost:9876/karma_webpack/vendor.js:85206:60) в функции.получить (http://localhost:9876/karma_webpack/vendor.js:85168:21) в R3TestBedCompiler.applyprovideroverridestмодуль (http://localhost:9876/karma_webpack/vendor.js:92502:39) в R3TestBedCompiler.compileTestМодуль (http://localhost:9876/karma_webpack/vendor.js:92750:14) в R3TestBedCompiler.завершить (http://localhost:9876/karma_webpack/vendor.js:92356:14) в TestBedRender3.получите testModuleRef [как testModuleRef] (http://localhost:9876/karma_webpack/vendor.js:93229:49) в TestBedRender3.введите (http://localhost:9876/karma_webpack/vendor.js:93152:29)

Ошибка: Ожидалось, что неопределенное будет правдивым. в в UserContext. (http://localhost:9876/karma_webpack/main.js:1060:23) в ZoneDelegate.invoke (http://localhost:9876/karma_webpack/polyfills.js:382:26) в ProxyZoneSpec.onInvoke (http://localhost:9876/karma_webpack/vendor.js:120678:39)

Код спецификации.ts выглядит следующим образом:

 import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Inject } from '@angular/core';
import { MenuComponent } from './menu.component';
import { Dish } from '../shared/dish';
import { DishService } from '../services/dish.service';
import { flyInOut, expand } from '../animations/app.animation';

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

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        Inject,
        Dish,
        DishService,
        flyInOut,
        expand
      ],
      declarations: [ MenuComponent ]
    })
    .compileComponents();
  });

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

  });

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

});
 

Код component.ts выглядит следующим образом:

 import { Component, OnInit, Inject } from '@angular/core';
import { Dish } from '../shared/dish';
import { DishService } from '../services/dish.service';
import { flyInOut, expand } from '../animations/app.animation';

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.scss'],
  // tslint:disable-next-line:use-host-property-decorator
  host: {
    '[@flyInOut]': 'true',
    'style': 'display: block;'
    },
  animations: [
    flyInOut(),
    expand()
  ]
})
export class MenuComponent implements OnInit {

  dishes!: Dish[];
  errMess: string;
  
  constructor(private dishService: DishService, 
    @Inject ('BaseURL') public baseURL) { }

  ngOnInit(): void {
    this.dishService.getDishes().subscribe((dishes => this.dishes = dishes), errMess => this.errMess = <any>errMess);
  }

}
 

Это код dish.service.ts:

 import { Injectable } from '@angular/core';
import { Dish } from '../shared/dish';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { baseURL } from '../shared/baseurl';
import { map, catchError } from 'rxjs/operators';
import { ProcessHTTPMsgService } from './process-httpmsg.service';

@Injectable({
  providedIn: 'root'
})
export class DishService {

  constructor(private http: HttpClient, private processHTTPMsgService: ProcessHTTPMsgService) { }

  getDishes(): Observable<Dish[]> {
    return this.http.get<Dish[]>(baseURL   '/dishes').pipe(catchError(this.processHTTPMsgService.handleError));
  }

  getDish(id: string): Observable<Dish> {
    return this.http.get<Dish>(baseURL   '/dishes/'   id).pipe(catchError(this.processHTTPMsgService.handleError));
  }

  getFeaturedDish(): Observable<Dish> {
    return this.http.get<Dish[]>(baseURL   '/dishes?featured=true').pipe(map(dishes => dishes[0])).pipe(catchError(this.processHTTPMsgService.handleError));
  }

  getDishIds(): Observable<string[] | any> {
    return this.getDishes().pipe(map(dishes => dishes.map(dish => dish.id))).pipe(catchError(error => error));
  }

  putDish(dish: Dish): Observable<Dish> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json'})
    };
    return this.http.put<Dish>(baseURL   '/dishes/'   dish.id, dish, httpOptions).pipe(catchError(this.processHTTPMsgService.handleError));
  }
}
 

Ценю вашу помощь

Ответ №1:

массив импорта ожидает только модуль(например, FormsModule, модуль перевода и т. Д.). Здесь вы добавляете услуги в список импорта.

Вместо этого, пожалуйста, добавьте его в список поставщиков в свой файл spec.ts.

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

  // mocking service to avoid actual HTTP calls
  const mockDishService = {
     getDishes: () => {
        // sample JSON similar to api response
        return {
           id: '000',
           name: 'nnnnn'
        }
     }
  }

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [], // no module dependency so keeping it []
      declarations: [ MenuComponent ],
      providers: [
        { provide: DishService, useValue: mockDishService }
      ]
    })
    .compileComponents();
  });

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

  });

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

});
 

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

1. Я внес изменения, но у меня та же проблема, не могли бы вы проверить новый код?

2. Я отредактировал свой ответ. Я видел, что вы добавили макет сериала в app.module. ts, который не требуется. Насмешка над сервисом вернет фиктивные данные только для целей тестирования

3. Спасибо за обновление, я внес изменения, теперь у меня следующая ошибка: NullInjectorError: R3InjectorError(DynamicTestModule)[baseUrl -> baseUrl]: NullInjectorError: Нет поставщика для baseUrl!. Я запускаю приложение, получающее информацию от localhost:3000 во время выполнения json-server-смотрите db.json, чтобы имитировать, что я получаю информацию с сервера

4. в файле MenuComponent.ts удалите код @Inject ('BaseURL') public baseURL , если вы не используете переменную baseURL

5. Готово, спасибо за вашу помощь !!!