在使用隔离范围的指令上运行测试时,似乎无法获得对适当范围的引用。为了清楚起见,对于继承范围的测试,我没有这个问题。
问题表明,对于$httpBackend.expectPOST()
调用,我指定了预期的数据。
$httpBackend.expectPOST('/notes/'+scope.note.id+'/replies', {
content: 'This is the reply' /*** TEST PASSES IF EXPECTED POST DATA IS NOT SET ***/
}).respond(200, {
id: 11,
noteId: 199,
content: 'This is the reply'
});
当我调用elem.find('[ng-click="saveReply()"]').click()
时,范围saveReply()被调用,但是没有设置的数据被提交,所以if if我指定它失败的预期数据,但是如果我没有指定它传递的预期数据。显然,要进行更完整的测试,我想执行前者。
如上所述,在调用click()方法之后调用saveReply()方法。这会导致人们认为适当的范围绑定已经到位,但是如果我直接设置范围变量,它仍然没有在范围方法中看到。也许这就是问题/解决方案的所在......
我认为可以通过elem.scope()
获得所需的范围引用,但是当我这样做时,elem.scope()与$ rootScope相同。
// FAILS
expect(elem.scope().$id).not.toEqual($rootScope.$id);
有什么想法吗?
'use strict';
describe('Note directive', function () {
var scope, elem;
var compile = function($compile, $rootScope, PhotoService) {
spyOn(PhotoService, 'profilePhotoUrl').andReturn('mypic.jpg');
scope = $rootScope;
scope.note = {
id: 199,
content: 'This is the note',
author: {
firstName: 'Jim',
lastName: 'Smith',
name: 'Jim Smith',
profilePhotoName: 'mypic.jpg'
},
replies: [
{id: 99, content: 'you should not see this on initial load', author: {
firstName: 'Jim', lastName: 'Smith', name: 'Jim Smith', profilePhotoName: 'mypic.jpg'}
},
{id: 99, content: 'but you should see this one', author: {
firstName: 'Jim', lastName: 'Smith', name: 'Jim Smith', profilePhotoName: 'mypic.jpg'}
}
]
};
elem = $compile('<note data="note"></note>')(scope);
scope.$digest();
};
var stubCurrentUser = function ($httpBackend) {
$httpBackend.expectGET('/users/me').respond({id: 99, name: 'Jim Smith', role: 'owner'});
};
beforeEach(module('woddy'));
beforeEach(module('directive_templates'));
beforeEach(inject(stubCurrentUser, compile));
iit('allows the user to reply to a note', inject(function ($httpBackend) {
$httpBackend.expectPOST('/notes/'+scope.note.id+'/replies', {
content: 'This is the reply' /*** TEST PASSES IF EXPECTED POST DATA IS NOT SET ***/
}).respond(200, {
id: 11,
noteId: 199,
content: 'This is the reply'
});
expect(elem.find('[ng-repeat="reply in note.replies"]').length).toBe(2);
elem.find('[ng-click="reply()"]').click();
scope.$digest();
elem.find('[ng-model="content"]').text("This is the reply");
scope.$digest();
elem.find('[ng-click="saveReply()"]').click();
$httpBackend.flush();
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
scope.$digest();
expect(elem.find('[ng-repeat="reply in note.replies"]').length).toBe(3);
}));
});
指令
'use strict';
angular.module('woddy').directive('note', function() {
return {
restrict: 'E',
scope: {
note: '=data'
},
templateUrl: '/dashboard/note.html',
controller: function($scope, PhotoService, Reply, CurrentUser) {
$scope.state = 'show';
$scope.showAllReplies = false;
CurrentUser.get().then(function(user) {
$scope.currentUser = user;
});
/**
* Reply on the note
*/
$scope.reply = function() {
$scope.content = '';
$scope.state = 'add';
};
/**
* Revert back to the default view
*/
$scope.reset = function() {
$scope.content = 'Add a comment...';
$scope.state = 'show';
};
$scope.saveReply = function() {
console.log("It is calling the method")
var reply = new Reply({
noteId: $scope.note.id,
content: $scope.content
});
reply.$save(function() {
var author = $scope.currentUser;
$scope.note.replies.push({
content: $scope.content,
author: {
id: author.id,
name: author.name,
photoName: author.photoName,
gender: author.gender
}
});
$scope.reset();
});
};
}
};
});
查看
<div class="note box">
<img class="author" ng-src="{{authorPhotoUrl()}}" alt="{{note.author.name}}"/>
<div class="details">
<div class="name" ng-bind="note.author.name"></div>
<div class="timestamp" timestamp="{{note.timestamp}}"></div>
</div>
<div class="content" ng-bind-html="note.content"></div>
<div class="note-replies" ng-if="note.replies.length > 0">
<div class="links">
<span>{{note.replies.length}} {{note.replies.length == 1 ? 'Comment' : 'Comments'}}</span>
<a href="#" ng-show="!showAllReplies && note.replies.length > 1" ng-click="showAllReplies = true">Show Comments</a>
<a href="#" ng-show="showAllReplies && note.replies.length > 1" ng-click="showAllReplies = false">Hide Comments</a>
</div>
<div class="replies">
<div class="reply" ng-repeat="reply in note.replies" ng-show="showAllReplies || $last">
<img ng-src="{{replyAuthorPhotoUrl(reply.author)}}" alt="{{reply.author.name}}">
<div class="reply-details">
<span class="name" ng-bind="reply.author.name"></span>
<span class="timestamp" timestamp="{{reply.timestamp}}"></span>
<div class="content" ng-bind-html="reply.content"></div>
</div>
</div>
</div>
</div>
<div class="reply-form">
<div class="reply-content" ng-click="reply()" contenteditable="true" ng-model="content">Add a comment...</div>
<form ng-show="state == 'add'">
<div class="text-right">
<button class="secondary" ng-click="reset()">Cancel</button>
<button ng-click="saveReply()">Comment</button>
</div>
</form>
</div>
</div>
答案 0 :(得分:0)
在AngularJs 1.2中,您可以使用elem.isolateScope()
来访问指令隔离范围。
这是一个有关的例子: http://plnkr.co/edit/x0c0HYfyVMfsV8LX2bZX?p=preview