Reputation: 27
I am writing my unit test for my Angular component, in one component I called service which helping register reader in backend. In test, I mocked the service, but each time I still get error with not injecting dependency of the original service, why? My understanding is we should not consider those dependencies once I mock the service.
Following is error: Chrome 92.0.4515.159 (Mac OS 10.15.7) RegisterComponent should create FAILED NullInjectorError: R3InjectorError(DynamicTestModule)[ReaderAuthService -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient! error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'ReaderAuthService', 'HttpClient', 'HttpClient' ] }) NullInjectorError: R3InjectorError(DynamicTestModule)[ReaderAuthService -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient! at NullInjector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11100:1) at R3Injector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11267:1) at R3Injector.get (node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11267:1)
Following is my test code:
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();
});
});
Following is code of my component:
@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')
}
}
}
Upvotes: 0
Views: 1145
Reputation: 3727
You have a typo, change
Provide: ReaderAuthService,
to
provide: ReaderAuthService,
Upvotes: 0