我在主模板中定义了一个全局变量,我用它来存储来自后端的信息位,例如环境上下文路径。我无法在服务中移动该变量。
当我运行单元测试时,如何将该变量公开给Karma?
答案 0 :(得分:58)
您可以在测试文件中声明该全局变量:
var global = "something";
describe('Your test suit', function() {
...
});
或添加一个Javascript文件,将其定义到karma.conf.js
文件:
// list of files / patterns to load in the browser
files: [
...,
'file-containing-the-global-variable.js'
],
答案 1 :(得分:5)
第一个解决方案在Angular 2.1.x中对我不起作用。它根本无法识别我导入的服务中的变量。我必须做的是将我的环境变量放在我的karma-test-shim.js
文件中并删除var
,以便全局可用。
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('reflect-metadata');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy'),
require('zone.js/dist/sync-test'),
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
// Add environment variables here so that tests will inject them in source code
API_URL = 'http://localhost:8080/api/';
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(
browser.BrowserDynamicTestingModule,
browser.platformBrowserDynamicTesting()
);
答案 2 :(得分:5)
如果您来自Angular 2+,我发现可行的唯一方法是使用window
全局创建变量或对象:
从脚本加载Google Recapthca:
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
在此示例中,对Google Recaptcha的调用将创建一个名为grecaptcha
的全局变量。
在我们的组件中,我们决定渲染一个新的Google Recaptcha。当然,因为我们没有声明grecaptcha
,所以我们需要使用declare var
来说嘿,我保证它是在某个地方声明的:
declare var grecaptcha;
private CreateGoogleCaptcha() {
grecaptcha.render('recaptcha', {
sitekey: this.siteKey,
callback: this.GoogleCaptchaCallback,
badge: 'inline'
});
}
private GoogleCaptchaCallback(token) {
// Handle Callback Logic
}
现在我们的函数起作用了,我们决定运行测试,但是我们当然想模拟grecaptcha
,因为我们无法控制它。
因此,我们命名我们要创建并添加我们想要的函数的全局变量:
beforeEach(() => {
fixture = TestBed.createComponent(GoogleRecaptchaComponent);
component = fixture.componentInstance;
window['grecaptcha'] = {
render() {
console.log('mocked global variable and function');
}
}
}
在beforeEach
中创建全局变量很好,但是当它具有某种回调函数(如上述)从您的组件中调用函数时,该怎么办呢?很简单,我们只需将登录名移至测试中,并在模拟中将其设置为组件功能:
it('should ', () => {
window['grecaptcha'] = {
render: function() { GoogleRecaptchaComponent['GoogleCaptchaCallback']('token'); }
};
spyOn<any>(GoogleRecaptchaComponent, 'GoogleCaptchaCallback');
GoogleRecaptchaComponent['CreateGoogleCaptcha']();
expect(GoogleRecaptchaComponent['GoogleCaptchaCallback']).toHaveBeenCalled();
});
注意::spyOn<any>
:使用<any>
是因为它是私有的,因此我们可以毫无错误地引用该函数,否则会出现打字稿错误;