我在我的主模板中定义了一个全局变量,我用它来存储来自后端的信息位,例如环境上下文路径。我无法在服务中移动该变量。
运行单元测试时,如何将该变量公开给 Karma?
我在我的主模板中定义了一个全局变量,我用它来存储来自后端的信息位,例如环境上下文路径。我无法在服务中移动该变量。
运行单元测试时,如何将该变量公开给 Karma?
您可以在测试文件中声明该全局变量:
var global = "something";
describe('Your test suit', function() {
...
});
或在您的文件中添加一个 Javascriptkarma.conf.js
文件:
// list of files / patterns to load in the browser
files: [
...,
'file-containing-the-global-variable.js'
],
如果您来自 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
说 hey I promise 它在某处声明:
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>
是因为它是私有的,所以我们可以正确引用该函数,否则我们会得到一个打字稿错误;
第一个解决方案在 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()
);