【问题标题】:Angular test error - what to provide for injection token角度测试错误 - 为注入令牌提供什么
【发布时间】:2020-10-23 10:38:24
【问题描述】:

我正在为使用带有注入令牌的配置服务的注册页面编写测试。我得到的错误如下:

NullInjectorError: R3InjectorError(DynamicTestModule)[FuseConfigService -> InjectionToken fuseCustomConfig -> InjectionToken fuseCustomConfig]: 
  NullInjectorError: No provider for InjectionToken fuseCustomConfig!

我不确定要提供什么。我尝试从 angular core 导入和提供 InjectionToken 模块,但这导致了另一个错误,因为它实际上不是一个模块。

Error: Unexpected value 'InjectionToken' imported by the module 'DynamicTestModule'. Please add an @NgModule annotation.

我尝试了其他一些方法,例如创建和提供注入令牌,但无法正常工作。我对注入令牌不太熟悉,而且我很难弄清楚问题是什么以及如何解决它。

这里是测试文件:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegisterComponent } from './register.component';
import { AbstractControl, FormBuilder, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/internal/operators';
import { FuseConfigService } from '@fuse/services/config.service';
import { fuseAnimations } from '@fuse/animations';
import { AuthService } from 'app/main/services/auth.service';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from "@angular/router/testing";
import { PlatformModule } from '@angular/cdk/platform';
import { Inject, Injectable, InjectionToken } from '@angular/core';


import { mockItems } from 'app/main/services/mockItems';

import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatCheckboxModule } from '@angular/material/checkbox';



export const FUSE_CONFIG = new InjectionToken('fuseCustomConfig');


fdescribe('RegisterComponent', () => {
    let component: RegisterComponent;
    let fixture: ComponentFixture<RegisterComponent>;


    let MockGroup = new mockItems();







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




    beforeEach(() => {


        
        TestBed.configureTestingModule({
            imports: [ MatIconModule,
                       MatFormFieldModule,
                       MatCheckboxModule,
                       ReactiveFormsModule,
                       RouterTestingModule,
                       BrowserAnimationsModule,
                       PlatformModule,
                       InjectionToken ],
            declarations: [ RegisterComponent ],
            providers: [ { provide: FuseConfigService },
                         { provide: FormBuilder },
                         { provide: AuthService,        useValue : {} } ]

        });


        fixture = TestBed.createComponent(RegisterComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });




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



});

配置服务文件的相关部分。

import { Inject, Injectable, InjectionToken } from '@angular/core';
import { ResolveEnd, Router } from '@angular/router';
import { Platform } from '@angular/cdk/platform';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
import * as _ from 'lodash';

// Create the injection token for the custom settings
export const FUSE_CONFIG = new InjectionToken('fuseCustomConfig');

@Injectable({
    providedIn: 'root'
})
export class FuseConfigService
{
    // Private
    private _configSubject: BehaviorSubject<any>;
    private readonly _defaultConfig: any;

    /**
     * Constructor
     *
     * @param {Platform} _platform
     * @param {Router} _router
     * @param _config
     */
    constructor(
        private _platform: Platform,
        private _router: Router,
        @Inject(FUSE_CONFIG) private _config
    )
    {
        // Set the default config from the user provided config (from forRoot)
        this._defaultConfig = _config;

        // Initialize the service
        this._init();
    }

【问题讨论】:

    标签: angular unit-testing karma-jasmine angular-test


    【解决方案1】:

    你需要在你的 spec.ts:: 中这样写

    { provide: FUSE_CONFIG, useFactory: 'your_factory_function' }

    useValue 或 useFactory 基于注入令牌的配置方式。

    我们编写测试来模拟 InjectToken 和依赖项,而不是创建另一个。

    【讨论】:

    • 对不起,我仍然遇到同样的错误。什么是工厂函数?
    • FUSE_CONFIG 的实现。你可能已经在你的 app.module 中做了类似的事情
    • 用一些空函数/值来模仿它,然后在你的测试中设置它:)
    • 我试过嘲笑它。我没有发现这样做没有错误
    • 我了解在测试中设置注入令牌。但是,测试将失败,除非为 FuseConfigService 提供了某些内容,并且我尝试提供的所有内容都会导致上述错误。在测试本身中提供令牌与为测试文件提供适当的项目以编译是不同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 2015-04-05
    • 2017-03-11
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多