问题描述
我是新手,AngularJs /世界的NodeJS,所以原谅,如果这是一个基本的问题,一些。
I'm newbie to AngularJs/NodeJs world, so forgive if this is a basic question to some.
所以,总之我有两个控制器,第一控制器 $广播
的'ID',第二控制器读取的编号与 $在
,然后通过该ID来一个中间服务
,这使得一个 $ HTTP
AJAX调用并返回一个图书
对象。
So in a nutshell I've two controllers, the first controller $broadcast
an 'Id' and the second controller fetches that Id with $on
and then passes that Id to an intermediate service
, which makes an $http
ajax call and returns a single Book
object.
如何使用茉莉花我做单元测试$ scope.broadcast,$范围。$
How do I unit test $scope.broadcast, $scope.$on using Jasmine
.controller('firstCtrl', function($scope, ...){
$scope.selectGridRow = function() {
if($scope.selectedRows[0].total !=0)
$scope.$broadcast('id', $scope.selectedRows[0].id);//Just single plain ID
};
});
secondCtrl
.controller('secondCtrl',
function($scope, bookService) {
$scope.$on('id', function(event, id) {
bookService.getBookDetail(id).then(function(d) {
$scope.book = d.book;
});
});
});
预期的Json OBJ
var arr = "book" : [ {
"id" : "1",
"name" : "Tomcat",
"edition" : "9.1"
}
]
让我知道,如果有人要我张贴的使用由第二控制器 $ HTTP
服务。
所以从我的头顶,理想情况下,我想测试各种可能的情况,但类似下面,这样就可以消耗:
So from the top of my head, ideally, I would like to test every possible scenario, but something like below, which can then expend:
expect(scope.book).toEqual(arr);
expect(scope.book).not.toEqual(undefined);
谢谢大家!
推荐答案
首先,你应该做 $ rootScope
广播,那么你可以接收 $范围
。
现在到了测试。我假设你想包括通过 bookService的
和 $ HTTP
来您的API真正的要求。这可以被嘲笑,但我会专注于实际通话。让我知道如果你需要的嘲笑之一。
First you should do the broadcast on $rootScope
then you can receive on $scope
.Now to the testing. I assume you want to include real request to your API via bookService
and $http
. This can be mocked but I'll focus on the real call. Let me know if you need the mocked one.
在实际测试之前,您需要做一些注射/实例:
Before the actual test, you will need to do some injections/instantiations:
- 初始化你的应用程序
- 注入
$控制器
,$ rootScope
,$ httpBackend
和bookService的
- 创建为firstController和SecondController范围并将其存储在一个变量
- 存储
bookService的
和$ httpBackend
变量 - 实例化控制器,并将它们存储
- Initialize your app
- Inject
$controller
,$rootScope
,$httpBackend
andbookService
- Create scopes for firstController and SecondController and store it in a variable
- Store
bookService
and$httpBackend
in variables - Instantiate the controllers and store them
然后在实际测试中,你必须告诉 $ httpBackend
时,它会缓存书(或电子书)的要求做什么。构建 $ httpBackend.whenGET(/ API /书籍/ 1)直通();
将通过与URL请求/ API /书籍/ 1
到服务器。
接下来你必须设置属性 selectedRows
在 firstScope
所以它满足函数的条件 selectGridRow
在 firstCtrl
。
Then in the actual test you must tell $httpBackend
what to do when it caches request for the books (or books). Construct $httpBackend.whenGET("/api/books/1").passThrough();
will pass request with url "/api/books/1"
to the server.Next your must setup property selectedRows
on firstScope
so it fulfills the condition in function selectGridRow
in your firstCtrl
.
现在,你可以调用函数 selectGridRow
来触发广播和API调用。但是,你必须在运行
功能,使茉莉花认识到这是一个异步调用,并会等待它完成包裹。在等待在 waitsFor
调用所定义。它会等待,直到它得到一本书,它会等待最多5000毫秒然后根据试验失败将被标记。
Now you can call function selectGridRow
to trigger the broadcast and API call. But you must wrap it in runs
function so Jasmine recognizes this as an async call and will wait for it to finish. The 'waiting' is defined in waitsFor
call. It will wait until it gets a book and it waits max 5000 ms then the test will be marked as failed.
最后一步是检查预期的结果。我们没有检查未定义
了,因为测试不会得到到这里反正。支票必须重新包装所以它执行afters运行
呼叫成功waitsFor。
Last step is to check expected result. We don't have to check for undefined
anymore as the test would not get to here anyway. The check must be wrapped again runs
call so it is executed afters successful 'waitsFor'.
下面是完整的code:
Here is the full code:
describe("Broadcast between controllers", function () {
beforeEach(module('app')); //app initialization
var firstScope;
var secondScope;
var bookService;
var $httpBackend;
var firstController;
var secondController;
beforeEach(inject(function ($controller, $rootScope, _bookService_, _$httpBackend_) {
firstScope = $rootScope.$new();
secondScope = $rootScope.$new();
bookService = _bookService_;
$httpBackend = _$httpBackend_;
firstController = $controller('firstCtrl', { $scope: firstScope });
secondController = $controller('secondCtrl', { $scope: firstScope, bookService: bookService });
}));
it("should work", function () {
$httpBackend.whenGET("/api/books/1").passThrough();
firstScope.selectedRows = [{ id: 1, total: 1000 }];
secondScope.book = null;
runs(function () {
firstScope.selectGridRow();
});
waitsFor(function () {
return secondScope.book != null;
}, "Data not received in expected time", 5000);
runs(function () {
expect(secondScope.book[0].id).toEqual(1);
});
});
});
这篇关于我如何单元测试$ scope.broadcast,$范围。$使用茉莉花的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!