gpt4 book ai didi

angularjs-directive - 如何捕获 $compile 或 $digest 错误? (带有 templateUrl 的 AngularJS 指令)

转载 作者:行者123 更新时间:2023-12-04 08:08:44 26 4
gpt4 key购买 nike

我正在编写 AngularJS 1.x 指令的单元测试。
如果我使用"template",它可以工作。
如果我使用“templateUrl”它不起作用(指令元素保持相同的原始 HTML 而不是“编译”)。

这就是我创建指令元素以在 Jasmine 中测试的方式:

function createDirectiveElement() {
scope = $rootScope.$new();
var elementHtml = '<my-directive>my directive</my-directive>';
var element = $compile(elementHtml)(scope);
scope.$digest();
if (element[0].tagName == "my-directive".toUpperCase()) throw Error("Directive is not compiled");

return element;
};

(这实际上不起作用,请参阅更新以获取真实代码)

我正在使用 this workaround使用来自 ngMockE2E 的 $httpBackend(而不是 ngMock 中的那个)。在浏览器开发人员的“网络”选项卡中,我没有看到对模板文件的任何请求。它似乎有效,因为我解决了错误“对象#没有方法'passThrough'”。

我知道对模板的调用是使用 $httpBackend 异步完成的(这意味着在模板真正应用之前 $compile 退出)。

我的问题是:
显然 $compile 没有达到我的预期。如何捕获此错误?
如果我在 templateUrl 中使用了错误的地址,我不会收到任何错误。
当我调用 $compile(directive) 或 scope.$digest() 时,我怎么能发现问题发生了?

谢谢,
亚历克斯

[解决]

正如@Corvusoft 所建议的,我注入(inject) $exceptionHandler 并在每次测试后检查错误。
最后,这是我添加的唯一代码:

afterEach(inject(function ($exceptionHandler) {
if ($exceptionHandler.errors.length > 0)
throw $exceptionHandler.errors;
}));

现在我可以清楚地看到 Jasmine 测试结果中出现的错误(而不是在控制台中搜索它们),例如:
错误:意外请求:GET/api/category/list
不再有请求,错误:意外请求:GET/api/category/list
预计不会再抛出更多请求

而且,最重要的是,如果出现一些错误,我的测试不会通过。

[更新显示真实案例]

实际上,使 templateUrl 工作的真正代码使用异步 beforeEach(“完成”)和超时等待编译/摘要结束。
我的指令使用一些 prividers/services,模板包含其他指令,这些指令反过来使用它们的 templateUrl 并在链接函数()中调用一些 API。

这是当前(工作)测试代码:

// workaround to have .passThrough() in $httpBackend
beforeEach(angular.mock.http.init); // set $httpBackend to use the ngMockE2E to have the .passThrough()
afterEach(angular.mock.http.reset); // restore the $httpBackend to use ngMock

beforeEach(inject(function (_$compile_, _$rootScope_, _$http_, $httpBackend, $templateCache, $injector) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$http = _$http_;

$httpBackend.whenGET(/\/Scripts of my app\/Angular\/*/).passThrough();
$httpBackend.whenGET(/\/api\/*/).passThrough(); // comment out this to see the errors in Jasmine
}));

afterEach(inject(function ($exceptionHandler) {
if ($exceptionHandler.errors.length > 0)
throw $exceptionHandler.errors;
}));

beforeEach(function(done) {
createDirectiveElementAsync(function (_element_) {
element = _element_;
scope = element.isolateScope();
done();
});
});

function createDirectiveElementAsync(callback) {
var scope = $rootScope.$new();
var elementHtml = '<my-directive>directive</my-directive>';
var element = $compile(elementHtml)(scope);
scope.$digest();

// I haven't found an "event" to know when the compile/digest end
setTimeout(function () {
if (element.tagName == "my-directive".toUpperCase()) throw Error("Directive is not compiled");
callback(element);
}, 0.05*1000); // HACK: change it accordingly to your system/code
};

it("is compiled", function () {
expect(element).toBeDefined();
expect(element.tagName).not.toEqual("my-directive".toUpperCase());
});

我希望这个例子对其他人有所帮助。

最佳答案

$exceptionHandler

Any uncaught exception in AngularJS expressions is delegated to this service. The default implementation simply delegates to $log.error which logs it into the browser console.

In unit tests, if angular-mocks.js is loaded, this service is overridden by mock $exceptionHandler which aids in testing.


angular.
module('exceptionOverwrite', []).
factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) {
return function myExceptionHandler(exception, cause) {
logErrorsToBackend(exception, cause);
$log.warn(exception, cause);
};
}]);

关于angularjs-directive - 如何捕获 $compile 或 $digest 错误? (带有 templateUrl 的 AngularJS 指令),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42192977/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com