AngularJS+;CanvasJS:如何进行单元测试?
我正试图在使用Yeoman构建的AngularJS应用程序中运行单元测试。 我尝试运行的唯一测试只是检查和数组的长度是否正确,但失败了 因为一些与画布有关的事情 这是日志AngularJS+;CanvasJS:如何进行单元测试?,angularjs,unit-testing,canvasjs,Angularjs,Unit Testing,Canvasjs,我正试图在使用Yeoman构建的AngularJS应用程序中运行单元测试。 我尝试运行的唯一测试只是检查和数组的长度是否正确,但失败了 因为一些与画布有关的事情 这是日志 LOG: 'CanvasJS Error: Chart Container with id "chartContainer" was not found' PhantomJS 1.9.7 (Windows 7) Controller: MainCtrl should attach a list of inputs to the
LOG: 'CanvasJS Error: Chart Container with id "chartContainer" was not found'
PhantomJS 1.9.7 (Windows 7) Controller: MainCtrl should attach a list of inputs to the scope FAILED
TypeError: 'undefined' is not an object (evaluating 'this._toolBar.appendChild')
at /path/to/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:1799
at /path/to/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:1919
at /path/to/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:2093
at /path/to/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:12551
at /path/to/Chart/app/scripts/controllers/main.js:101
at invoke (/path/to/Chart/app/bower_components/angular/angular.js:3869)
at instantiate (/path/to/Chart/app/bower_components/angular/angular.js:3880)
at /path/to/Chart/app/bower_components/angular/angular.js:7134
at /path/to/Chart/test/spec/controllers/main.js:15
at invoke (/path/to/Chart/app/bower_components/angular/angular.js:3869)
at workFn (/path/to/Chart/app/bower_components/angular-mocks/angular-mocks.js:2147)
undefined
Expected 0 to be 3.
PhantomJS 1.9.7 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.025 secs / 0.021 secs)
Warning: Task "karma:unit" failed. Use --force to continue.
可以在这里找到应用程序
我不确定我是否在AngularJS应用程序中正确实现了这个库,建议将非常感谢
谢谢
-------------------编辑#1--------------------
下面是一些代码,可以更好地理解场景,正如您所看到的CanvasJS
作为全局库使用,而不是作为服务注入,因此问题之一是,如果没有bower回购协议,那么以这种方式使用第三方库是否正确
我认为这条线是问题的根源
...
$scope.chart = new CanvasJS.Chart('chartContainer', {
...
控制器视图包含“chartContainer”id
Karma.conf.js有所有必需的文件,我想
....
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-animate/angular-animate.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-touch/angular-touch.js',
'app/bower_components/jquery/dist/jquery.js',
'app/bower_components/angular-ui/build/angular-ui.js',
'app/bower_components/jquery-ui/jquery-ui.js',
'app/scripts/vendor/canvasjs-1.5.0-beta/canvasjs.min.js',
'app/scripts/directives/directive.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
],
...
-------------------编辑#2--------------------
这就是我在收到建议后编辑main.js测试的方式
beforeEach(inject(function ($controller, $rootScope, $compile) {
var htmlString = '' +
'<div ng-controller="MainCtrl">' +
' <div id="chartContainer">' +
'</div>'
;
var element = angular.element(htmlString)
scope = $rootScope.$new();
$compile(element)(scope);
scope.$digest();
MainCtrl = $controller('MainCtrl', {
$scope: scope
});
}));
更新测试控制器时我是否出错
-------------------编辑#3--------------------
在Ivarni的宝贵帮助下,我最终得到了以下解决方案:
在应用程序控制器中
...
$scope.chart = new $window.CanvasJS.Chart('chartContainer', {
...
在控制器测试中
...
beforeEach(inject(function ($controller, $rootScope, $compile, $window) {
$window.CanvasJS = { Chart: function(){
this.render = function() {};
} };
...
CanvasJS现在被模拟,UnitTest可以运行:)我认为您关于导致错误的原因的假设是正确的。您的控制器未连接到DOM,因此它无法定位id为“chartContainer”的任何对象是合理的 对于单元测试,我将尝试与对指令进行单元测试相同的方法。 这是一种类似于
beforeEach(inject(function($rootScope, $compile) {
var htmlString = '' +
'<div ng-controller="MainCtrl">' +
' <div id="chartContainer">' +
'</div>'
;
element = angular.element(htmlString)
scope = $rootScope.$new();
$compile(element)(scope);
scope.$digest();
}));
beforeach(注入(函数($rootScope,$compile){
var htmlString=''+
'' +
' ' +
''
;
元素=角度元素(htmlString)
scope=$rootScope.$new();
$compile(元素)(范围);
范围。$digest();
}));
这将编译一个附加了控制器的最小DOM片段和一个具有CanvasJS所需id的元素。你可能还得再摆弄一点。我不认为使用CanvasJS作为全局配置有问题,只要您确保它包含在karma配置中
另一种探索途径是查看Angular的e2e测试功能。这里有一些文档。当您测试DOM渲染时,这可能更适合。您好,我已经添加了整个主控制器、它的测试和Karma的配置。我试图对我的测试控制器进行一些编辑,但可能因为错误几乎相同而遗漏了一些内容。我将更新我的问题以获得更好的代码格式。嗯。。如果在编译和消化HTML片段之前初始化控制器会发生什么?如果仍然失败,那么我认为使用量角器/e2e是一种更可行的方法。量角器和e2e测试已经在队列中,但在进行e2e测试之前,我是否应该对需要它的控制器部分进行单元测试?谢谢你的帮助!我不认为e2e测试应该取代单元测试,但在某些情况下,某些功能不适合单元测试。通过包含CanvasJS,控制器已经没有被完全隔离地测试。我并不是说不可能在jasmine中运行,但我使用$compile的goto方法似乎不起作用。也许还有别的办法。如果控制器中有其他与画布无关的功能,那么提供CanvasJS的全局模拟实现仍然可以让您在单元测试中测试这些部分。确定。不要将CanvasJS构造函数作为全局(
new CanvasJS.Chart()
,顺便说一句,它相当于new window.CanvasJS.Chart()
),而是使用Angular的$window
服务包装窗口。现在,您的代码变成了new$window.CanvasJS.Chart()
。现在,您可以将一个模拟的$window
传递给您的控制器,就像您已经将$scope
传递给它一样。
LOG: 'CanvasJS Error: Chart Container with id "chartContainer" was not found'
PhantomJS 1.9.7 (Windows 7) Controller: MainCtrl should attach a list of inputs to the scope FAILED
TypeError: 'undefined' is not an object (evaluating 'this._toolBar.appendChild')
at /path/to/workspace/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:1799
at /path/to/workspace/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:1919
at /path/to/workspace/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:2093
at /path/to/workspace/Chart/app/scripts/vendor/canvasjs-1.5.0-beta/source/canvasjs.js:12551
at /path/to/workspace/Chart/app/scripts/controllers/main.js:101
at invoke (/path/to/workspace/Chart/app/bower_components/angular/angular.js:3869)
at instantiate (/path/to/workspace/Chart/app/bower_components/angular/angular.js:3880)
at /path/to/workspace/Chart/app/bower_components/angular/angular.js:7134
at /path/to/workspace/Chart/app/bower_components/angular/angular.js:6538
at forEach (/path/to/workspace/Chart/app/bower_components/angular/angular.js:330)
at nodeLinkFn (/path/to/workspace/Chart/app/bower_components/angular/angular.js:6552)
at compositeLinkFn (/path/to/workspace/Chart/app/bower_components/angular/angular.js:5986)
at publicLinkFn (/path/to/workspace/Chart/app/bower_components/angular/angular.js:5891)
at /path/to/workspace/Chart/test/spec/controllers/main.js:20
at invoke (/path/to/workspace/Chart/app/bower_components/angular/angular.js:3869)
at workFn (/path/to/workspace/Chart/app/bower_components/angular-mocks/angular-mocks.js:2147)
undefined
TypeError: 'undefined' is not an object (evaluating 'scope.inputs.length')
at /path/to/workspace/Chart/test/spec/controllers/main.js:28
PhantomJS 1.9.7 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.029 secs / 0.028 secs)
Warning: Task "karma:unit" failed. Use --force to continue.
...
$scope.chart = new $window.CanvasJS.Chart('chartContainer', {
...
...
beforeEach(inject(function ($controller, $rootScope, $compile, $window) {
$window.CanvasJS = { Chart: function(){
this.render = function() {};
} };
...
beforeEach(inject(function($rootScope, $compile) {
var htmlString = '' +
'<div ng-controller="MainCtrl">' +
' <div id="chartContainer">' +
'</div>'
;
element = angular.element(htmlString)
scope = $rootScope.$new();
$compile(element)(scope);
scope.$digest();
}));