我已经嘲笑了服务,为什么在不注入服务依赖性的情况下仍然会出错?

I already mocked the service why still get error with not injecting dependency of service?

我正在为我的 Angular 组件编写单元测试,在我称为服务的一个组件中,它帮助在后端注册 reader。在测试中,我模拟了该服务,但每次我仍然因为没有注入原始服务的依赖而出错,为什么?我的理解是,一旦我模拟了服务,我们就不应该考虑这些依赖关系。

错误如下: Chrome 92.0.4515.159 (Mac OS 10.15.7) RegisterComponent 应该创建失败 NullInjectorError:R3InjectorError(DynamicTestModule)[ReaderAuthService -> HttpClient -> HttpClient]: NullInjectorError:没有 HttpClient 的提供者! 错误属性:Object({ ngTempTokenPath: null, ngTokenPath: [ 'ReaderAuthService', 'HttpClient', 'HttpClient' ] }) NullInjectorError:R3InjectorError(DynamicTestModule)[ReaderAuthService -> HttpClient -> HttpClient]: NullInjectorError:没有 HttpClient 的提供者! 在 NullInjector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11100:1) 在 R3Injector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11267:1) 在 R3Injector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11267:1)

以下是我的测试代码:

fdescribe('RegisterComponent', () => {
  let regComponent: ReaderRegisterComponent;
  let fixture: ComponentFixture<ReaderRegisterComponent>;
  let registerSpy: jasmine.Spy;
  let router: jasmine.SpyObj<Router>;

  beforeEach(async () => {
    const authServiceSpy = jasmine.createSpyObj('ReaderAuthService', ['register']);
    registerSpy = authServiceSpy.register.and.returnValue(of(readerStub()));
    const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
    const loggerSpy = jasmine.createSpyObj('NGXLogger', ['info', 'warn', 'error']);

    await TestBed.configureTestingModule({
      providers: [
        {
          Provide: ReaderAuthService,
          useValue: authServiceSpy,
        },
        {
          provide: Router,
          useValue: routerSpy,
        },
        {
          provide: NGXLogger,
          useValue: loggerSpy,
        },
        FormBuilder,
      ],
      imports: [
        RouterTestingModule,
        ReactiveFormsModule,
      ],
      declarations: [ReaderRegisterComponent]
    })
      .compileComponents();
    router = TestBed.inject(Router) as jasmine.SpyObj<Router>;
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ReaderRegisterComponent);
    regComponent = fixture.componentInstance;
    fixture.detectChanges();
  });

  fit('should create', () => {
    expect(regComponent).toBeTruthy();
  });
});

以下是我的组件代码:

@Component({
  selector: 'app-reader-register',
  templateUrl: './reader-register.component.html',
  styleUrls: ['./reader-register.component.css']
})
export class ReaderRegisterComponent implements OnInit {

  constructor(
    private router: Router,
    private fb: FormBuilder,
    private readerAuthService: ReaderAuthService,
    private logger: NGXLogger,
  ) { }

  registerForm = this.fb.group({
    username: ['', [Validators.minLength(3), Validators.pattern('[a-zA-Z0-9_]*')]],
    password: ['', Validators.minLength(5)],
    confirmPassword: ['', Validators.minLength(5)],
    email: ['', Validators.email],
    firstName: [''],
    lastName: [''],
    gender: [''],
    birthday: [''],
    phoneNumber: [''],
    homeAddress: [''],
    province: [''],
    postcode: [''],
    securityQuestion: ['', Validators.required],
    securityAnswer: ['', Validators.required],
  })

  ngOnInit(): void {
    // Disable form submissions if there are invalid fields
    (function () {
      // Fetch all forms we want to apply custom validation styles to
      var forms = document.querySelectorAll('.needs-validation')

      // Loop over them and prevent submission
      Array.prototype.slice.call(forms)
        .forEach(function (form) {
          form.addEventListener('submit', function (event) {
            if (!form.checkValidity()) {
              event.preventDefault()
              event.stopPropagation()
            }
            form.classList.add('was-validated')
          }, false)
        })
    })()
  }

  register() {
    const val: RegisterReaderDto = this.registerForm.value;
    if (val.confirmPassword === val.password) {
      this.readerAuthService.register(val).subscribe((data) => {
        if (!data) {
          window.alert('The username already exist, please choose another one.');
          return null;
        }
        this.logger.info(`User ${data.username} already successfully registered in system.`);
        this.router.navigateByUrl('/reader/login');
      })
    } else {
      this.logger.warn('Passwords are not matched, please check')
      window.alert('Passwords are not matched, please check')
    }
  }
}

你打错了,改一下

Provide: ReaderAuthService,

provide: ReaderAuthService,