2016-08-17 3 views
1

Еще в июне 2016 года я написал статью о том, как тестировать приложения Angular 2. В качестве отправной точки я использовал angular2-seed.Ошибка: токен должен быть определен! при тестировании с помощью Angular 2 RC5

https://raibledesigns.com/rd/entry/testing_angular_2_0_rc1

я решил переписать этот учебник, используя Угловое CLI (от его главной ветви), которая использует Угловые 2 RC5. Я вижу странную ошибку из одного из моих тестов.

Error: Token must be defined! 
    at new BaseException (/Users/mraible/ng2-demo/src/test.ts:1940:23 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/facade/exceptions.js:27:0) 
    at new ReflectiveKey (/Users/mraible/ng2-demo/src/test.ts:27600:19 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:36:0) 
    at KeyRegistry.get (/Users/mraible/ng2-demo/src/test.ts:27641:22 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:77:0) 
    at Function.ReflectiveKey.get (/Users/mraible/ng2-demo/src/test.ts:27615:35 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_key.js:51:0) 
    at ReflectiveInjector_.get (/Users/mraible/ng2-demo/src/test.ts:58418:62 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/di/reflective_injector.js:586:0) 
    at NgModuleInjector.get (/Users/mraible/ng2-demo/src/test.ts:40942:52 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/src/linker/ng_module_factory.js:98:0) 
    at TestBed.get (/Users/mraible/ng2-demo/src/test.ts:11910:47 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:269:0) 
    at /Users/mraible/ng2-demo/src/test.ts:11916:61 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:275:46 
    at Array.map (native) 
    at TestBed.execute (/Users/mraible/ng2-demo/src/test.ts:11916:29 <- webpack:///Users/mraible/ng2-demo/~/@angular/core/testing/test_bed.js:275:0) 

Вот мой тест:

import { provide } from '@angular/core'; 
import { TestComponentBuilder } from '@angular/compiler/testing'; 

import { MockActivatedRoute } from '../shared/search/mocks/routes'; 
import { MockSearchService } from '../shared/search/mocks/search.service'; 

import { EditComponent } from './edit.component'; 
import { ActivatedRoute } from "@angular/router"; 
import { inject } from "@angular/core/testing/test_bed"; 

describe('Component: Edit',() => { 
    var mockSearchService:MockSearchService; 

    beforeEach(() => { 
    mockSearchService = new MockSearchService(); 

    return [ 
     mockSearchService.getProviders(), 
     provide(ActivatedRoute, { useValue: new MockActivatedRoute({ 'id': '1' }) }) 
    ]; 
    }); 

    it('should fetch a single record', inject([TestComponentBuilder], (tcb:TestComponentBuilder) => { 
    return tcb.createAsync(EditComponent).then((fixture) => { 
     let person = {name: 'Emmanuel Sanders', address: {city: 'Denver'}}; 
     mockSearchService.setResponse(person); 

     fixture.detectChanges(); 
     // verify service was called 
     expect(mockSearchService.getByIdSpy).toHaveBeenCalledWith(1); 

     // verify data was set on component when initialized 
     let editComponent = fixture.debugElement.componentInstance; 
     expect(editComponent.editAddress.city).toBe('Denver'); 

     // verify HTML renders as expected 
     var compiled = fixture.debugElement.nativeElement; 
     expect(compiled.querySelector('h3')).toBe('Emmanuel Sanders'); 
    }); 
    })); 
}); 

Я отправил этот проект GitHub, так что вы можете воспроизвести этот вопрос, если вам нравится: https://github.com/mraible/ng2-demo.

+0

любое везение найти решение для этого? Я сталкиваюсь с той же проблемой при попытке модульного тестирования через 'ng test' с помощью инструмента угловой кли. –

+0

Это было вызвано моим импортом - мне пришлось изменить его на 'import {TestBed} из '@ angular/core/testing';'. Вы можете увидеть весь тест здесь: https://github.com/mraible/ng2-demo/blob/master/src/app/edit/edit.component.spec.ts –

ответ

1

Мэтт, я скопировал в том, что я думаю, соответствующие строки your working code, чтобы помочь любому, кто может споткнуться об этом вопросе в будущем.

Вы упомянули ваше исправление было импортировать TestBed из @angular/core/testing, и я заметил, что вы также следовал указаниям инъекционного имитировали услуг, таким образом, что нашло отражение в angular testing documentation and guidelines, а также.

Мое исправление было немного иным; это произошло из-за неправильного использования одной из услуг, которые я предоставил в методе TestBed.configureTestingModule().

Например, в вашем случае, вы экземпляр нового MockSearchService и передать его в providers массив в mockSearchService, как таковой: {provide: SearchService, useValue: mockSearchService}.

В моем случае, я прошел в MockSearchServiceтипа (Примечание, фактический тип, а не экземпляра), следующим образом: {provide: SearchService, useValue: MockSearchService} (обратите внимание на капитализацию) ...

... а затем получил экземпляр службы следующим образом: mockSearchService = fixture.debugElement.injector.get(MockSearchService);.

Однако в моем случае я неправильно записал значение, которое я передал как ...injector.get(mockSearchService), который был недействительным токеном, чтобы перейти в инжекторный геттер. Таким образом, я думаю, что эта недопустимая ошибка токена выбрасывается Karma или одним из других инструментов, участвующих в тестовом процессе, как уловка всех случаев для попытки доступа или передачи в токене, который не определен. Мораль истории, скорее всего, это было связано с неправильным пониманием переменной. Ваше дело немного другое, но я почти уверен, что это было связано как-то:]. Ура!

Ваш рабочий код

import { MockSearchService } from '../shared/search/mocks/search.service'; 
// other imports ... 

describe('Component: Edit',() => { 
    let mockSearchService: MockSearchService; 
    // other service declarations... 

    beforeEach(() => { 
     mockSearchService = new MockSearchService(); 
     // other service instances... 

     TestBed.configureTestingModule({ 
      // declarations... 

      providers: [ 
       {provide: SearchService, useValue: mockSearchService}, 

       // other providers... 
      ], 

      // imports... 
     }); 
    }); 

    // Tests ... 

}); 
Смежные вопросы