用Jest进行角度指令的单元测试 [英] Unit testing Angular Directives with Jest
问题描述
在这种极其简化的角度指令单元测试中,我觉得我缺少了一些关键的东西:
I feel I am missing something crucial in this extremely simplified angular directive unit test:
import * as angular from 'angular'
import 'angular-mocks'
const app = angular.module('my-app', [])
app.directive('myDirective', () => ({
template: 'this does not work either',
link: (scope, element) => { // have also tried compile fn
console.log('This does not log')
element.html('Hi!')
}
}))
describe('myDirective', () => {
var element, scope
beforeEach(app)
beforeEach(inject(($rootScope, $compile) => {
scope = $rootScope.$new()
element = $compile('<my-directive />')(scope)
scope.$digest()
}))
it('should actually do something', () => {
expect(element.html()).toEqual('Hi!')
})
})
玩笑运行时,该指令似乎尚未链接/编译/任何内容
When jest runs it appears the directive has not been linked/compiled/whatever
FAIL test/HtmlToPlaintextDirective.spec.js
● myDirective › should actually do something
expect(received).toEqual(expected)
Expected value to equal:
"Hi!"
Received:
""
推荐答案
更新后的答案:
您是正确的,将所有内容导入单个文件时,事情并没有按预期进行.
You're right things don't work as expected when importing everything in a single file.
深入研究似乎就像遇到了Babel/Jest支持基于全局变量的浏览器脚本(例如AngularJS)所做的那样.
Digging into things it looks like you're running into some magic that Babel/Jest does to support browser scripts that rely on globals (like AngularJS).
正在发生的事情是,模块的angular
变量不与对角global可见的全局angular
变量相同.
What's happening is that your module's angular
variable is not the same as the global angular
variable that is visible to angular-mocks.
您可以通过在其中一项测试的顶部运行此命令来对此进行检查:
You can check this by running this at the top of one of your tests:
import * as angular from 'angular'
import 'angular-mocks'
console.log(angular === window.angular); // `false` in Jest!
console.log(angular.mock); // undefined
console.log(window.angular.mock); // `{...}` defined
要解决此问题,您只需要在测试中使用全局angular
变量即可.
To work around this you just need to use the global angular
variable in your tests.
src/__ test __/all-in-one.test.js :
import "angular";
import "angular-mocks";
/*
Work around Jest's window/global mock magic.
Use the global version of `angular` that has been augmented by angular-mocks.
*/
var angular = window.angular;
export var app = angular.module('app', []);
app.directive('myDirective', () => ({
link: (scope, element) => {
console.log('This does log');
scope.content = 'Hi!';
},
template: 'content: {{content}}'
}));
describe('myDirective', function(){
var element;
var scope;
beforeEach(function(){
angular.mock.module(app.name);
});
it('should do something', function(){
inject(function(
$rootScope,
$compile
){
scope = $rootScope.$new();
element = $compile('<my-directive></my-directive>')(scope);
scope.$digest();
});
expect(element.html()).toEqual('content: Hi!');
});
});
原始答案:(之所以奏效,是因为我在测试中意外使用了angular
的全局版本.)
Original answer: (This worked because I was accidentally using the global version of angular
inside my test.)
测试中的Angular模块未在测试中正确初始化.
The Angular module under test isn't being initialised correctly in your tests.
您对beforeEach(app)
的呼叫不正确.
相反,您需要使用angular.mock.module("moduleName")
初始化模块.
Instead you need to use angular.mock.module("moduleName")
to initialise your module.
describe('myDirective', () => {
var element, scope
// You need to pass the module name to `angular.mock.module()`
beforeEach(function(){
angular.mock.module(app.name);
});
// Then you can set up and run your tests as normal:
beforeEach(inject(($rootScope, $compile) => {
scope = $rootScope.$new()
element = $compile('<my-directive></my-directive>')(scope)
scope.$digest()
}))
it('should actually do something', () => {
expect(element.html()).toEqual('Hi!')
})
});
然后您的测试按我的预期进行:
And then your test works as expected for me:
PASS src\__test__\app.test.js
myDirective
√ should do something (46ms)
作为参考,这里是完整的应用程序和测试:
For reference, here is the full app and test:
src/app/app.module.js :
import * as angular from 'angular'
export var app = angular.module('app', []);
app.directive('myDirective', () => ({
link: (scope, element) => {
console.log('This does log');
scope.content = 'Hi!';
},
template: 'content: {{content}}'
}))
src/__ test __/app.test.js :
import {app} from "../app/app.module";
import "angular-mocks";
describe('myDirective', function(){
var element;
var scope;
beforeEach(function(){
angular.mock.module(app.name);
});
beforeEach(inject(function(
$rootScope,
$compile
){
scope = $rootScope.$new();
element = $compile('<my-directive></my-directive>')(scope);
scope.$digest();
}));
it('should do something', function(){
expect(element.html()).toEqual('content: Hi!');
});
});
这篇关于用Jest进行角度指令的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!