【问题标题】:Angular 2 (5) Testbed no provider for MyServiceAngular 2 (5) Testbed 没有 MyService 的提供者
【发布时间】:2018-08-10 02:17:25
【问题描述】:

我在测试角度组件时遇到问题。我查看了几个堆栈溢出帖子,但我仍然卡住了。

无论我尝试什么,我都会在 jasmine 中收到以下错误:

错误:StaticInjectorError[RestApiService]:NullInjectorError:没有 RestApiService 的提供者!

这里有几个sn-ps的代码:

我的组件类:

@Component({
    moduleId: module.id,
    selector: 'book-form',
    templateUrl: './book-form.component.html',
    styleUrls: ['./book-form.component.css'],
    providers: [
        RestApiService
    ]
})
export class BookFormComponent implements OnInit {
    model = new Book(1, '', '', '', '');
    severities: Observable<KeyValue[]>;

    constructor(private restApiService: RestApiService) { }

    ngOnInit() {
        this.severities = this.restApiService.getSeverities();
    }
}

我的模拟服务:

export class RestApiSeviceSpy {

    getSeverities(): Observable<any> {
        return Observable.of('some data');
    }

    getAssets(): Observable<any> {
        return Observable.of('some data');
    }
}

我的 beforeEach 方法(修改后):

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [BookFormComponent],
        providers: [{ provide: RestApiService, useClass: RestApiSeviceSpy }],
        imports: [
            MatDatepickerModule,
            MatNativeDateModule,
            MatFormFieldModule,
            MatInputModule,
            FormsModule,
            HttpModule,
            NoopAnimationsModule],
        schemas: [NO_ERRORS_SCHEMA]
    })
        .compileComponents().then(() => {
            let service = TestBed.get(RestApiService);
            fixture = TestBed.createComponent(BookFormComponent);
            component = fixture.componentInstance;
            fixture.detectChanges();
        });
}));

任何有关如何解决此问题的见解将不胜感激。

谢谢

编辑

这是我的服务代码。我还编辑了上面@Injectable() 的坏副本。

@Injectable()
export class RestApiService {
    constructor(private http: Http) {

    }

    getSeverities(): Observable<KeyValue[]> {
        return this.http.get('/api/RiskApi/GetSeverities').map(r => <KeyValue[]>r.json());
    }

    getAssets(): Observable<ApiAsset[]> {
        return this.http.get('/api/RiskApi/GetAssets').map(r => <ApiAsset[]>r.json());
    }
}

编辑 我更新了上面的代码以显示当前的 beforeEach 并显示更新的 spy/mock 类。

编辑 这是测试运行的输出:

业力开始 --run-once 01 03 2018 17:02:58.196:WARN [karma]: No captured browser, open @987654321@ 01 03 2018 17:02:58.226:INFO [karma]: Karma v2.0.0 server started at @987654322@ 01 03 2018 17:02:58.227:INFO [launcher]: Launching browser Chrome with unlimited concurrency 01 03 2018 17:02:58.231:INFO [launcher]: Starting browser Chrome 01 03 2018 17:02:58.963:INFO [Chrome 64.0.3282 (Windows 10.0.0)]: Connected on socket lxAY8w15N_373BOwAAAA with id 41860275 Chrome 64.0.3282 (Windows 10.0.0) BookFormComponent should create FAILED Error: StaticInjectorError[RestApiService]: NullInjectorError: No provider for RestApiService! at _NullInjector.get (node_modules/@angular/core/bundles/core.umd.js:1033:19) Chrome 64.0.3282 (Windows 10.0.0): Executed 3 of 4 (1 FAILED) (0 secs / 0 secs) Chrome 64.0.3282 (Windows 10.0.0) BookFormComponent should create FAILED Error: StaticInjectorError[RestApiService]: NullInjectorError: No provider for RestApiService! at _NullInjector.get (node_modules/@angular/core/bundles/core.umd.js:1033:19) Chrome 64.0.3282 (Windows 10.0.0) BookFormComponent should create FAILED Failed: Response with status: 404 Not Found for URL: @987654323@ at stack (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:2455:17) [object ErrorEvent] thrown Chrome 64.0.3282 (Windows 10.0.0): Executed 4 of 4 (2 FAILED) (0 secs / 0 secs) Chrome 64.0.3282 (Windows 10.0.0) BookFormComponent should create FAILED Failed: Response with status: 404 Not Found for URL: @987654324@ at stack (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:2455:17) Chrome 64.0.3282 (Windows 10.0.0): Executed 4 of 4 (2 FAILED) (0.311 secs / 0 secs)

【问题讨论】:

  • 为什么@Injectable() @Component 紧随其后?另外,你能发布你的服务吗?
  • Injectable 和 Component 是我的代码的错误副本
  • 我刚刚发现 Nadhir 的建议奏效了。我的问题是,一个不同的测试让我的组件测试看起来不起作用。

标签: angular unit-testing


【解决方案1】:

删除此行:
let spy: RestApiSeviceSpy = new RestApiSeviceSpy([], []);

现在在您的测试平台中:

providers:[ {provide: RestApiService,useClass: RestApiSeviceSpy}]//After you import your spy

现在,对于您的模拟/间谍,您不必使用真实服务对其进行扩展。 只需创建一个具有相同依赖项并返回一些虚假数据的服务即可。像这样:

export class RestApiSeviceSpy {

        getSeverities(): Observable<any> {
            return Observable.of('some data');
        }

        getAssets(): Observable<any> {
            return Observable.of('some data');
        }
    }

还有你的规格:

beforeEach(async(() => {

    TestBed.configureTestingModule({
        declarations: [BookFormComponent],
        providers: [{ provide: RestApiService, useValue: spy }],
        imports: [
            MatDatepickerModule,
            MatNativeDateModule,
            MatFormFieldModule,
            MatInputModule,
            FormsModule,
            HttpModule,
            NoopAnimationsModule],
        schemas: [NO_ERRORS_SCHEMA]
    });

       fixture = TestBed.createComponent(OrderEntryComponent);
       component = fixture.componentInstance;

}));

【讨论】:

  • 我不明白为什么,但它仍然不起作用。以下是相关行:TestBed.configureTestingModule({ declarations: [BookFormComponent], providers: [{ provide: RestApiService, useClass: RestApiSeviceSpy }], ... .overrideComponent(BookFormComponent, { set: { providers: [ { provide: RestApiService , useClass: RestApiServiceSpy } ] } })
  • @James 我更新了我的答案。尝试删除所有.overrideProvider .overrideComponent 部分
  • 我之前没有注意到这一点,但我收到了两次错误。现在我得到它一次,然后看起来我试图替换的服务已经构建并放置了 http 调用(不成功,因为我正在运行来自 karma 的测试并且后端服务没有运行)。我不确定版本是否重要,但我使用的是 5.2.3。
  • 好的,在你的间谍服务中删除整个构造函数,检查我更新的答案
  • 我更新了上面的代码以反映当前状态。我仍然收到错误消息。
猜你喜欢
  • 2018-11-17
  • 2018-08-04
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2015-07-26
  • 2018-01-09
相关资源
最近更新 更多