Karma试运行程序中的全局变量

6ojccjat  于 2022-10-24  发布在  Angular
关注(0)|答案(4)|浏览(175)

我在主模板中定义了一个全局变量,用于存储来自后端的信息位,如环境上下文路径。我不能在服务中移动该变量。
当我运行单元测试时,如何将该变量公开给Karma?

lbsnaicq

lbsnaicq1#

您可以在测试文件中声明该全局变量:

var global = "something";

describe('Your test suit', function() {
...
});

或者在karma.conf.js文件中添加一个定义了它的Java脚本文件:

// list of files / patterns to load in the browser
files: [
   ...,
   'file-containing-the-global-variable.js'
],
lokaqttq

lokaqttq2#

如果您来自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>,因为函数是私有的,所以可以正确引用,否则会出现打字错误;

erhoui1w

erhoui1w3#

第一个解决方案在2.1.xAngular 下对我不起作用。它根本无法识别我导入的服务中的变量。我要做的是将我的环境变量放在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()
);
v2g6jxz6

v2g6jxz64#

我试图在没有任何NPM包的情况下,将ANGLING V13与Google-Place-AutoComplete集成在一起,只是普通的Google-Place-AutoComplete。当我试着测试的时候,Karma说:‘’Google‘没有定义’。所以我找到了上面的锥子,它对我来说是这样的:
1.在根目录下创建了一个文件(在我的例子中,我命名为:google-place.js)
1.添加了一个包含Component中使用的指令的模拟对象。

class Autocomplete {
  constructor(input, options) {
    const addListener = (eventName, callback) => { }
    const getPlace = () => { }
    return { addListener, getPlace }
  }
}

var google = {
  maps: {
    places: {
      Autocomplete: Autocomplete
    }
  }
};

1.在karma.conf.js中添加了一个名为“files”的属性,并以如下方式结束:

files: [
  "./google-place.js"
]

而且没有必要在每个规范中都添加declare var google。现在是全球性的。

相关问题