Правильное использование TestBed в Angular

в проекте приложения на основе Angular 8.1.2 и Ionic 4 я написал модульные тесты для простого класса на машинописном языке. Это сработало с "npm test" нормально. Чтобы подготовиться к более сложным классам с необходимыми насмешками, я изменил код, чтобы использовать метод beforeEach и объект TestBed таким образом:

import { CryptHelper, CryptCodeTyp, CryptIOStringTyp } from './cryptHelper';
import { TestBed } from '@angular/core/testing';

describe('CryptHelper', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ CryptHelper ],
      imports: [ ],
      providers: [ CryptHelper ],
    }).compileComponents();
  });

  it('should be created', () => {
    let fixture = TestBed.createComponent(CryptHelper);
    let app = fixture.debugElement.componentInstance;
    expect(app).toBeDefined();
  });
});

Таким образом, я получаю в тестовом выводе сообщение об ошибке

error properties: Object({ ngSyntaxError: true })
Error: Unexpected value 'CryptHelper' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
    at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
    at http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19889:1
    at <Jasmine>
    at CompileMetadataResolver.getNgModuleMetadata (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19871:1)
    at JitCompiler._loadModules (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25582:1)
    at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25571:1)
    at JitCompiler.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25533:1)
    at CompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:237:1)
    at TestingCompilerImpl.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:140:1)
    at TestBedViewEngine.compileComponents (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3118:1)

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

...
    TestBed.configureTestingModule({
      declarations: [ ],
...

но это приводит меня к этому сообщению об ошибке:

error properties: Object({ ngSyntaxError: true })
Error: Illegal state: Could not load the summary for directive CryptHelper.
    at syntaxError (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
    at CompileMetadataResolver.getDirectiveSummary (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:19729:1)
    at JitCompiler.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/compiler/fesm2015/compiler.js:25536:1)
    at CompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/platform-browser-dynamic.js:263:30)
    at TestingCompilerImpl.getComponentFactory (http://localhost:9876/_karma_webpack_/node_modules/@angular/platform-browser-dynamic/fesm2015/testing.js:148:1)
    at TestBedViewEngine.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3418:1)
    at Function.createComponent (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/testing.js:3000:1)
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/core/services/cryptHelper.spec.ts:15:27)
    at <Jasmine>

Я нашел предложения написать имя класса в объявлениях. Но это приводит меня к верхнему сообщению об ошибке. Так что я не так? Любая помощь приветствуется.


person Andreas    schedule 12.12.2019    source источник
comment
является ли CryptHelper угловым @Component({...})?   -  person Andrei    schedule 12.12.2019


Ответы (2)


Предположим, что CryptHelper является компонентом:

    TestBed.configureTestingModule({
        declarations: [ CryptHelper], // Your testing component goes here
        providers: [ // Your component's providers goes here, for example a mocked service
            {
                provide: MyService, useValue: mockMyService
            }
        ],
        imports: [
            // imports from your component, for example MatDialogModule, MatInputModule, MyComponentModule, ...
        ]
    })
    .compileComponents();

Предположим, что CryptHelper — это служба:

let cryptHelper: CryptHelper;

beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [CryptHelper],
        imports: [] 
    });

    cryptHelper = TestBed.get(CryptHelper);
});

describe('CryptHelper Service creation', () => {
    it('should be created', inject([CryptHelper], (service: CryptHelper) => {
        expect(service).toBeTruthy();
    }));
});
person Pedro Bezanilla    schedule 12.12.2019
comment
Да это услуга. Так что ваше второе предложение работает. :-) Еще один вопрос. Когда полезно или необходимо использовать инъекцию? Так как прямое использование it('should be created', () => { ... }); тоже работает. - person Andreas; 12.12.2019
comment
Хороший :) . Что касается вашего вопроса, то... это синтаксис, который я использую при тестировании своих сервисов, но вы можете сделать это ("следует быть созданным", () => { const service: MyService = TestBed.get(MyService); expect(service ).toBeTruthy() }); и, я думаю, могут быть и другие способы... Надеюсь, это поможет ^^ - person Pedro Bezanilla; 12.12.2019

Как говорится в ваших журналах, CryptHelper НЕ является компонентом. поэтому правильным тестом для него было бы использование его в качестве службы (если вы планируете использовать его как элемент DI). вот рабочий пример:

describe('CryptHelper', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [ CryptHelper ],
    });
  });

  it('should be created', () => {
    let fixture = TestBed.get(CryptHelper);
    let app = fixture.debugElement.componentInstance;
    expect(app).toBeDefined();
  });
});

как вы можете заметить, TestBed.get используется вместо TestBed.createComponent

person Andrei    schedule 12.12.2019
comment
Спасибо, я понял, но по сравнению с другим ответом Педро Б. и после тестирования приспособление объекта уже содержит объект. Итак, let app = ... не работает, поэтому я отметил другое решение как правильное. - person Andreas; 12.12.2019