【发布时间】:2020-02-22 09:15:21
【问题描述】:
我有一个 AppConfigService,它将 JSON 文件中的对象加载到作为服务一部分的静态设置变量中。整个应用程序中的各种组件和/或服务使用 AppConfigService.settings. 引用对象,使用简单引用(无注入)。如何测试引用这种结构的服务?
例如
@Injectable()
export class SomeService {
someVariable;
constructor() {
// I can't get the test to not give me a TypeError: Cannot read property 'someSettingsVariable' of undefined on this line
this.someVariable = AppConfigService.settings.someSettingsVariable;
}
}
我有两个项目,一个使用 Jest,另一个使用 Jasmine/Karma,我需要弄清楚如何让测试在这个构造中工作的模式。
我尝试过类似的方法:
const spy = spyOnProperty(SomeService, 'someVariable')
.and.returnValue('someValue');
示例规范:
import { TestBed } from '@angular/core/testing';
import { NgRedux } from '@angular-redux/store';
import { Injectable } from '@angular/core';
import { DispatchHelper } from '../reducers/dispatch.helper';
import { ContributorActions } from '../actions/contributor.action';
import { MockDispatchHelper } from '../_mocks/DispatchHelperMock';
import { DiscrepancyService } from '../discrepancies/discrepancy.service';
import { DiscrepancyAPIService } from '../discrepancies/discrepancy-api.service';
import { DiscrepancyAPIServiceMock } from '../_mocks/DiscrepancyAPIServiceMock';
import { Observable } from 'rxjs';
import { Guid } from 'guid-typescript';
import { getInitialUserAccountState } from '../functions/initial-states/user-account-initial-state.function';
import { LoggingService } from '../security/logging/logging.service';
import { MockLoggingService } from '../_mocks/LoggingServiceMock';
describe('discrepancyService', () => {
let discrepancyService: DiscrepancyService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: Injectable, useClass: Injectable },
{ provide: DispatchHelper, useClass: MockDispatchHelper },
{ provide: ContributorActions, useClass: ContributorActions },
{ provide: NgRedux, useClass: NgRedux },
{ provide: DiscrepancyService, useClass: DiscrepancyService },
{ provide: DiscrepancyAPIService, useClass: DiscrepancyAPIServiceMock },
{ provide: LoggingService, useClass: MockLoggingService },
]
})
.compileComponents();
const userStateObservable = Observable.create(observer => {
const userState = getInitialUserAccountState();
userState.userId = Guid.parse('<guid>');
userState.organization_id = Guid.parse('<guid>');
observer.next(userState);
console.log('built user state observable');
observer.complete();
});
discrepancyService = TestBed.get(DiscrepancyService);
const spy4 = spyOnProperty(discrepancyService, 'userState$', 'get').and.returnValue(userStateObservable);
});
// TODO: Fix this
it('should create service and loadDiscrepancies', () => {
// in this example, discrepancyService constructor sets the
// value of a variable = ApiConfigService.settings.endPoint
// ApiConfigService.settings is static; how do I "replace"
// the value of endPoint in a call like this so I don't get
// an error because ApiConfigService.settings is undefined
// when called from a service in the test?
const spy = spyOn(discrepancyService.dispatcher, 'dispatchPayload');
discrepancyService.loadDiscrepancies();
expect(spy.calls.count()).toEqual(1);
});
});
karma.conf.js
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma'),
require('karma-spec-reporter')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly'],
fixWebpackSourcePaths: true
},
customLaunchers: {
ChromeDebug: {
base: 'Chrome',
flags: [ '--remote-debugging-port=9333','--disable-web-security' ]
},
ChromeHeadlessCI: {
base: 'Chrome',
flags: ['--no-sandbox', '--headless', '--watch=false'],
browserDisconnectTolerance: 10,
browserNoActivityTimeout: 10000,
browserDisconnectTimeout: 5000,
singleRun: false
}
},
reporters: ['progress', 'kjhtml', 'spec'],
port: 9876,
host: 'localhost',
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeDebug', 'ChromeHeadlessCI'],
singleRun: false
});
};
我们将不胜感激测试专家的任何帮助。
【问题讨论】:
-
请多分享一点你的规范文件,如果你也包括测试台的配置,你可能会得到解决问题的帮助
-
嗨 MapLion,请添加更多信息。您尝试过的应该可以工作,但是 someVariable 真的是一个属性还是只是一个变量成员?如果它是一个静态变量,只需更改值,而不是监视它。那里没有什么可窥探的。
-
对不起,我会这样做的。从技术上讲,这不是我的项目,但我会尝试获取更多信息。我以为我添加了相关的部分。
-
@AthanasiosKataras 我该如何“改变价值”,也许这就是我所缺少的。我通常不知道如何在另一个正在测试的函数中调用某些东西。
-
让我知道这三个是否适合您。
标签: angular testing jasmine jestjs angular8