在 Karma/Jasmine 中为 AngularJS 模拟模块依赖
Mocking Module Dependencies in Karma/Jasmine for AngularJS
我正尝试在 Karma/Jasmine 中为我项目中的特定模块编写一些单元测试,destination-filters
。
模块减速:
angular.module('destination-filter', ['ngSanitize']);
我的测试失败,除非我删除 ngSanitize
作为依赖项。据我了解,这是因为当模块被实例化时,它会尝试引入该依赖项,但因为在我的 spec.js 文件中我没有声明该模块失败。
规格文件:
describe('Destination Filter Controller', function () {
// Set the variables
var $controller;
var mockNgSanitize;
beforeEach(module('destination-filter'));
beforeEach(function() {
module(function($provide) {
$provide.value('ngSanitize', mockNgSanitize);
});
});
beforeEach(inject(function (_$controller_) {
$controller = _$controller_('DestinationFilterController');
}));
it('should expect the controller to not be null', function() {
// Check the controller is set
expect($controller).not.toBeNull();
});
});
以前,在模拟服务或功能时,$provide
方法已被证明非常有用,但我不确定我在这里使用它是否正确。我假设以这种方式使用的 $provide
不能模拟整个模块而是模拟服务?
澄清一下,如果我从我的模块减速中删除 ...['ngSantize'])...
,测试就会正确实例化。我收到的错误是 Error: [$injector:modulerr] destination-filter
在测试中使用 ngSanitize 时,您可以选择三个选项:
- 将服务注入您的测试
- 存根对 ngSanitize 的方法调用
- 模拟整个 ngSanitize 服务
您选择的选项实际上取决于在您的工作代码(而不是您的测试代码)中使用 ngSanitize。
无论你选择哪一个,你都需要在你的测试中提供服务,不需要 $provider
(这涵盖了选项 1,如果你只是想让它对你的过滤器可用):
beforeEach(module('ngSanitize'));
beforeEach(inject(function(_ngSanitize_) { // the underscores are needed
mockNgSanitize = _ngSanitize_;
}));
此外,请确保所有 js 文件都被 karma 拾取并加载。您可以通过将它们添加到 files:
属性.
来在 karma.conf.js
中定义它
2。在服务上存根一个方法
我喜欢存根,发现它们在编写测试时非常有用。你的测试应该只测试一件事,在你的情况下是一个过滤器。存根使您可以更好地控制测试,并允许您隔离被测对象。
通常是过滤器、控制器、任何调用许多其他东西的东西(服务或工厂,如 $http 或 ngSanitize)。
假设您的过滤器正在使用 ngSanitize 的 $sanitize
来清理一些 html 您可以将该方法存根以 return 清理您定义的 html 以测试您的期望:
// in a beforeEach
spyOn(mockNgSanitize, "$sanitize").and.returnValue('<some>sanitized<html>');
mockNgSanitized.$sanitize(yourDirtyHtml);
See the jasmine docs 了解更多信息。
您可能需要尝试监视正确的服务,但这应该没问题。
3。模拟整个服务
我认为你不想选择这个选项,因为它会让你疯狂地弄清楚什么需要模拟,而且模拟会产生不切实际的期望,而且对你的用例也不是特别有用。如果你真的想尝试一下,那么像下面这样的东西正朝着正确的方向前进(再次see the jasmine docs)
beforeEach(function() {
mockNgSanitize = ('ngSanitize', ['linky', '$sanitize', '$sanitizeProvider'];
});
it('mocks the ngSanitize service', function() {
expect(mockNgSanitize.linky).toBeDefined();
});
注意:在上面的所有代码中,请确保继续在描述块的顶部声明任何变量。
我正尝试在 Karma/Jasmine 中为我项目中的特定模块编写一些单元测试,destination-filters
。
模块减速:
angular.module('destination-filter', ['ngSanitize']);
我的测试失败,除非我删除 ngSanitize
作为依赖项。据我了解,这是因为当模块被实例化时,它会尝试引入该依赖项,但因为在我的 spec.js 文件中我没有声明该模块失败。
规格文件:
describe('Destination Filter Controller', function () {
// Set the variables
var $controller;
var mockNgSanitize;
beforeEach(module('destination-filter'));
beforeEach(function() {
module(function($provide) {
$provide.value('ngSanitize', mockNgSanitize);
});
});
beforeEach(inject(function (_$controller_) {
$controller = _$controller_('DestinationFilterController');
}));
it('should expect the controller to not be null', function() {
// Check the controller is set
expect($controller).not.toBeNull();
});
});
以前,在模拟服务或功能时,$provide
方法已被证明非常有用,但我不确定我在这里使用它是否正确。我假设以这种方式使用的 $provide
不能模拟整个模块而是模拟服务?
澄清一下,如果我从我的模块减速中删除 ...['ngSantize'])...
,测试就会正确实例化。我收到的错误是 Error: [$injector:modulerr] destination-filter
在测试中使用 ngSanitize 时,您可以选择三个选项:
- 将服务注入您的测试
- 存根对 ngSanitize 的方法调用
- 模拟整个 ngSanitize 服务
您选择的选项实际上取决于在您的工作代码(而不是您的测试代码)中使用 ngSanitize。
无论你选择哪一个,你都需要在你的测试中提供服务,不需要 $provider
(这涵盖了选项 1,如果你只是想让它对你的过滤器可用):
beforeEach(module('ngSanitize'));
beforeEach(inject(function(_ngSanitize_) { // the underscores are needed
mockNgSanitize = _ngSanitize_;
}));
此外,请确保所有 js 文件都被 karma 拾取并加载。您可以通过将它们添加到 files:
属性.
karma.conf.js
中定义它
2。在服务上存根一个方法
我喜欢存根,发现它们在编写测试时非常有用。你的测试应该只测试一件事,在你的情况下是一个过滤器。存根使您可以更好地控制测试,并允许您隔离被测对象。
通常是过滤器、控制器、任何调用许多其他东西的东西(服务或工厂,如 $http 或 ngSanitize)。
假设您的过滤器正在使用 ngSanitize 的 $sanitize
来清理一些 html 您可以将该方法存根以 return 清理您定义的 html 以测试您的期望:
// in a beforeEach
spyOn(mockNgSanitize, "$sanitize").and.returnValue('<some>sanitized<html>');
mockNgSanitized.$sanitize(yourDirtyHtml);
See the jasmine docs 了解更多信息。
您可能需要尝试监视正确的服务,但这应该没问题。
3。模拟整个服务
我认为你不想选择这个选项,因为它会让你疯狂地弄清楚什么需要模拟,而且模拟会产生不切实际的期望,而且对你的用例也不是特别有用。如果你真的想尝试一下,那么像下面这样的东西正朝着正确的方向前进(再次see the jasmine docs)
beforeEach(function() {
mockNgSanitize = ('ngSanitize', ['linky', '$sanitize', '$sanitizeProvider'];
});
it('mocks the ngSanitize service', function() {
expect(mockNgSanitize.linky).toBeDefined();
});
注意:在上面的所有代码中,请确保继续在描述块的顶部声明任何变量。