使用npm run test -- --no-watch --no-progress-command的Karma/Jasmine抛出以下错误:
Chrome 92.0.4515.159 (Mac OS 10.15.7) LoginComponent should create FAILED
TypeError: this.loggerService.onDebug is not a function
at LoginComponent.ngAfterViewInit (src/app/pages/login/login.component.ts:22:24)
at callHook (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2526:1)
at callHooks (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2495:1)
at executeInitAndCheckHooks (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2446:1)
at refreshView (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9516:1)
at renderComponentOrTemplate (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9559:1)
at tickRootContext (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10790:1)
at detectChangesInRootView (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10815:1)
at RootViewRef.detectChanges (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:22865:1)
at ComponentFixture._tick (node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:141:1)你好啊,
我正在用角度12.0.x写一个日志服务。服务连接到ngx-记录器(例如到外部服务器)和存储(Ngx)。
karma.conf.js-File以应用程序的根为目标。
几乎可以直接使用Logger (logging-service.ts):
import { Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import { NGXLogger } from 'ngx-logger';
import { AddLog, LogEntry } from '../store/log-state';
@Injectable({
providedIn: 'root',
})
export class LoggerService {
// This service pipes Log-Messages both to the store as well as to the NGXLogger.
// Further forwarding by the NGXLogger is dependent on the properties provided in the environment.ts-file.
constructor(private logger: NGXLogger, private store: Store) {}
private createLogEntry(level: string, origin: string, msg: string) {
const dateTime = new Date();
const log: LogEntry = {
time: dateTime,
level: level,
origin: origin,
msg: msg,
noticed: false,
};
return log;
}
onTrace(origin: string, msg: string) {
// To NGXLogger
this.logger.trace(msg);
// To Store
this.store.dispatch(new AddLog(this.createLogEntry('trace', origin, msg)));
}
onDebug(origin: string, msg: string) {
// To NGXLogger
this.logger.trace(msg);
// To Store
this.store.dispatch(new AddLog(this.createLogEntry('debug', origin, msg)));
}
onInfo(origin: string, msg: string) {
// To NGXLogger
this.logger.trace(msg);
// To Store
this.store.dispatch(new AddLog(this.createLogEntry('info', origin, msg)));
}
... ... ...
}从两个不同的位置调用Logger-Service's方法:
使用ng serve可以很好地工作。没什么问题。按预期工作。
尽管如此,使用npm run test -- --no-watch --no-progress-command运行Karma/Jasmine仍然会抛出显示在顶部的错误。删除Login-Component中的调用,Karma/Jasmine (=>,它只在Login-Component中)抛出的没有错误。因此,这两个组件导入Logger-Service的方式相同,但只有LoginComponent抛出错误。
区别:Login-Component在角度生命周期钩子中使用‘onInfo’-函数。ngOnInit()和ngAfterViewInit()都提供了相同的结果- Works (ng服务),但没有通过Karma/Jasmine。
我需要生命周期挂钩,因为我想跟踪访问的页面(在基本场景中)。
为了记录这两个受影响的文件:
import { Component, AfterViewInit } from '@angular/core';
import { LoggerService } from 'src/app/services/logging.service';
@Component({
selector: 'lep-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less'],
})
export class LoginComponent implements AfterViewInit {
constructor(
private loggerService: LoggerService,
) {}
ngAfterViewInit() {
this.loggerService.onDebug('Login', 'SampleMessage');
}
}import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoggerService } from 'src/app/services/logging.service';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [{ provide: LoggerService, useClass: class {} }],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});来自Log-Manager-Component的那些文件看起来(几乎)是一样的。如前所述,区别是在Log-Manager-Component中行..。
this.loggerService.onDebug('Login','SampleMessage');
。。在由html页面上的按钮触发的函数中。
有什么建议可以解决吗?:)
发布于 2021-08-25 09:39:37
在TestBed.configureTestingModule中的测试中,providers: [{ provide: LoggerService, useClass: class {} }]部件意味着应该提供一个空对象(我指的是{}),而不是作为模拟对象提供LoggerService。{}空对象没有onDebug函数,这就是在执行测试时抛出this.loggerService.onDebug is not a function错误的原因。(使用ng serve,应用程序可以工作,因为提供了LoggerService本身,它具有onDebug的实现。)
如下所示,如果您想在测试中为LoggerService拥有一个模拟对象,那么所需的函数必须从LoggerService本身进行模拟。例如,如果只需要onDebug函数:
await TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [{ provide: LoggerService, useClass: LoggerServiceMock }],
}).compileComponents();
...
// Outside of the jasmin describes
class LoggerServiceMock {
onDebug(origin: string, msg: string) {};
}作为示例,onDebug函数上面是一个空函数,这个空函数将在测试中调用,而不是在LoggerService的onDebug函数中调用。如果LoggerService本身是在测试中提供的,并且所需的函数是用jamsine间谍过度定义的,那么这种模拟对象的使用可能是不必要的。
发布于 2021-08-25 09:38:33
您的规范可能会失败,因为您正在使用一个空类作为模拟:
providers: [{ provide: LoggerService, useClass: class {} }]
因此,onDebug不是函数抛出的错误。
解决方案1 useValue
我建议传递一个模拟值(useValue:),其中包含一个onDebug函数:
providers: [{ provide: LoggerService, useValue: { onDebug: (origin: string, msg: string) => undefined} }]
解决方案2 useClass
您还可以提供一个简单的模拟类。
在你的文件中:
class LoggerServiceMock {
onDebug(origin: string, msg: string) { // we do nothing here }
}
...
...
providers: [{ provide: LoggerService, useClass: LoggerServiceMock }]https://stackoverflow.com/questions/68919021
复制相似问题