我正在使用依赖于 HttpClient 的服务编写一个简单的独立注销组件测试。我尝试了不同的解决方案来存根 HttpAuthService ,到目前为止我尝试的每个解决方案都抛出:
NullInjectorError:R3InjectorError(独立[LogoutComponent])[HttpAuthService - > HttpAuthService - > HttpClient - > HttpClient]: NullInjectorError:没有 HttpClient 的提供者!
我尝试存根的服务:
@Injectable({
providedIn: 'root'
})
export class HttpAuthService implements AuthService {
private userSignal = signal<User|null>(null);
private backendURL = environment.backendURL;
public user = computed<User | null>(this.userSignal);
constructor(private httpClient: HttpClient) {
}
login(params: { email: string; password: string }): Observable<void> {
return this.httpClient.get<any[]>(`${this.backendURL}/users?email=${params.email}`)
.pipe(
tap(result=> {
if (result.length > 0) {
this.userSignal.set({userName: result[0].email})
}
}),
map( result => {
if (result.length == 0) {
throw new Error('User not found');
} else {
return undefined;
}
})
)
}
logout(): void {
this.userSignal.set(null);
}
}
注销组件:
@Component({
selector: 'app-logout',
standalone: true,
imports: [MatButtonModule, MatIconModule],
template: `
<button mat-icon-button (click)="onLogout()" >
<mat-icon>logout</mat-icon>
</button>
`,
styles: ``
})
export class LogoutComponent {
constructor(private authService: HttpAuthService) {
}
onLogout() {
this.authService.logout();
}
}
注销单元测试:
describe('LogoutComponent', () => {
let component: LogoutComponent;
let fixture: ComponentFixture<LogoutComponent>;
const fakeAuthService = new AuthStub();
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LogoutComponent],
providers: [{provide: HttpAuthService, useClass: AuthStub}]
})
.compileComponents();
fixture = TestBed.createComponent(LogoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
export class AuthStub implements AuthService {
login(params: { email: string; password: string }): Observable<void> {
return of(undefined);
}
logout(): void {
}
}
尝试过的解决方案:
为了排除 IDE (Webstorm),我还在终端中使用 ng test 运行了测试。测试设置使用默认的 ng Karma/jasmine 测试设置和 Playwright 进行 e2e 测试。
你能尝试一下这个代码吗,我认为由于它是独立的组件,所以需要以不同的方式实例化!
describe('LogoutComponent', () => {
let component: LogoutComponent;
let fixture: ComponentFixture<LogoutComponent>;
beforeEach(async () => {
fixture = await render(LogoutComponent, {
providers: [
{
provide: HttpAuthService,
useValue: {
logout: () => { }
}
}
]
});
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});