为什么我的 Angular 应用程序的 jasmine 测试失败
Why is my jasmine test failing for my Angular app
我有以下代码...其中一个测试失败了。请帮助我理解原因,并建议我纠正的方法。
<html>
<head>
<!-- Jasmine References -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/boot.min.js"></script>
<!-- Angular and Angular Mock references -->
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular-mocks.js"></script>
<!-- The code we need to test -->
<script type="text/javascript" src="/js/index.js"></script>
</head>
<body></body>
<script type="text/javascript">
var app = angular.module('peoplesearchApp',[]);
app.controller('peopleSearchCtrl',function($scope,$http){
$scope.textChanged = function() {
// obtain the list of user whose name have the given prefix
$http.get('/findusers?q='+$scope.searchString.trim()).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.searchString = "";
$scope.textChanged();
});
describe('search people app tests', function () {
var $controller, $httpBackend, $scope;
// setup before each test run
beforeEach(module('peoplesearchApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_) {
$controller = _$controller_;
$scope = {};
$httpBackend = _$httpBackend_;
}));
describe('only the users that have their names starting from the search query should be visible', function () {
it('should show all users for a blank query', function () {
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$controller('peopleSearchCtrl', {$scope: $scope});
$httpBackend.flush();
expect($scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
});
it('should show only Rory for query=r', function () {
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
});
})
</script>
</html>
编辑:问题是在第二个测试中,我想在发出假 http 请求之前以某种方式设置 $scope.searchString = "r"
。我不知道该怎么做。
错误是:
Error: Unexpected request: GET /findusers?q=
Expected GET /findusers?q=r
我看到的直接问题是,
beforeEach(inject(function(_$controller_, _$httpBackend_, _$rootScope_) {
$controller = _$controller_;
scope = _$rootScope_.$new();
您应该从 $rootScope 创建新范围。
更新:
如果这没有帮助,请分享您遇到的错误。
it('should show only Rory for query=r', function () {
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$scope.searchString = 'r';
$scope.textChanged();
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
请检查这是否有帮助。
稍微修改一下代码的设计
app.controller('peopleSearchCtrl',function($scope,$http){
console.log($scope);
$scope.textChanged = function(_searched) {
// obtain the list of user whose name have the given prefix
$http.get('/findusers?q='+_searched.trim()).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.searchString = "";
$scope.textChanged($scope.searchString);
});
失败的测试现在正在运行:
it('should show only Rory for query=r', function () { //faking the initialize call of the controller
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$scope.textChanged('r');
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
我在随附的代码中发现了几个问题:
1. 您为每个不正确的测试实例化 $controller。控制器应该在顶层实例化,我们应该在需要的地方使用该控制器实例。这样我们就可以减少代码重复,提高测试执行时间。
您已添加$scope.searchString = ""; $scope.textChanged(); 执行之前的行;从编码的角度来看,这看起来不太好。在 textChanged() 本身中,我们应该检查 $scope.searchString 是否为空白或未定义,并据此创建 Rest URL。
在第二个测试中,我们必须将以下几行放在开头:
httpBackend.when('GET', '/findusers?q=')
.respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);否则它会抱怨 /findusers?q= url
我稍微修改了上面的代码,现在可以使用了:
<html>
<head>
<!-- Jasmine References -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/boot.min.js"></script>
<!-- Angular and Angular Mock references -->
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular-mocks.js"></script>
</head>
<body></body>
<script type="text/javascript">
var app = angular.module('peoplesearchApp',[]);
app.controller('peopleSearchCtrl',function($scope,$http){
$scope.textChanged = function() {
// obtain the list of user whose name have the given prefix
var searchUsers = ($scope.searchString) ? $scope.searchString.trim(): "";
$http.get('/findusers?q=' + searchUsers).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.textChanged();
});
describe('search people app tests', function () {
var controller, httpBackend, scope;
// setup before each test run
beforeEach(module('peoplesearchApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
controller = _$controller_('peopleSearchCtrl', {$scope: scope});
}));
describe('only the users that have their names starting from the search query should be visible', function () {
it('should show all users for a blank query', function () {
httpBackend.when('GET', '/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
scope.textChanged();
httpBackend.flush();
expect(scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
});
it('should show only Rory for query=r', function () {
httpBackend.when('GET', '/findusers?q=')
.respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
scope.searchString = 'r';
httpBackend.when('GET', '/findusers?q=r')
.respond(['Rory']);
scope.textChanged();
httpBackend.flush();
expect(scope.users).toEqual(['Rory']);
});
});
})
</script>
</html>
希望能解决您的问题。
干杯!
我有以下代码...其中一个测试失败了。请帮助我理解原因,并建议我纠正的方法。
<html>
<head>
<!-- Jasmine References -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/boot.min.js"></script>
<!-- Angular and Angular Mock references -->
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular-mocks.js"></script>
<!-- The code we need to test -->
<script type="text/javascript" src="/js/index.js"></script>
</head>
<body></body>
<script type="text/javascript">
var app = angular.module('peoplesearchApp',[]);
app.controller('peopleSearchCtrl',function($scope,$http){
$scope.textChanged = function() {
// obtain the list of user whose name have the given prefix
$http.get('/findusers?q='+$scope.searchString.trim()).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.searchString = "";
$scope.textChanged();
});
describe('search people app tests', function () {
var $controller, $httpBackend, $scope;
// setup before each test run
beforeEach(module('peoplesearchApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_) {
$controller = _$controller_;
$scope = {};
$httpBackend = _$httpBackend_;
}));
describe('only the users that have their names starting from the search query should be visible', function () {
it('should show all users for a blank query', function () {
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$controller('peopleSearchCtrl', {$scope: $scope});
$httpBackend.flush();
expect($scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
});
it('should show only Rory for query=r', function () {
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
});
})
</script>
</html>
编辑:问题是在第二个测试中,我想在发出假 http 请求之前以某种方式设置 $scope.searchString = "r"
。我不知道该怎么做。
错误是:
Error: Unexpected request: GET /findusers?q=
Expected GET /findusers?q=r
我看到的直接问题是,
beforeEach(inject(function(_$controller_, _$httpBackend_, _$rootScope_) {
$controller = _$controller_;
scope = _$rootScope_.$new();
您应该从 $rootScope 创建新范围。
更新:
如果这没有帮助,请分享您遇到的错误。
it('should show only Rory for query=r', function () {
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$scope.searchString = 'r';
$scope.textChanged();
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
请检查这是否有帮助。
稍微修改一下代码的设计
app.controller('peopleSearchCtrl',function($scope,$http){
console.log($scope);
$scope.textChanged = function(_searched) {
// obtain the list of user whose name have the given prefix
$http.get('/findusers?q='+_searched.trim()).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.searchString = "";
$scope.textChanged($scope.searchString);
});
失败的测试现在正在运行:
it('should show only Rory for query=r', function () { //faking the initialize call of the controller
$httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
$httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
$controller('peopleSearchCtrl', {$scope: $scope});
$scope.textChanged('r');
$httpBackend.flush();
expect($scope.users).toEqual(['Rory']);
});
我在随附的代码中发现了几个问题: 1. 您为每个不正确的测试实例化 $controller。控制器应该在顶层实例化,我们应该在需要的地方使用该控制器实例。这样我们就可以减少代码重复,提高测试执行时间。
您已添加$scope.searchString = ""; $scope.textChanged(); 执行之前的行;从编码的角度来看,这看起来不太好。在 textChanged() 本身中,我们应该检查 $scope.searchString 是否为空白或未定义,并据此创建 Rest URL。
在第二个测试中,我们必须将以下几行放在开头: httpBackend.when('GET', '/findusers?q=') .respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);否则它会抱怨 /findusers?q= url
我稍微修改了上面的代码,现在可以使用了:
<html>
<head>
<!-- Jasmine References -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine-html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/boot.min.js"></script>
<!-- Angular and Angular Mock references -->
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular-mocks.js"></script>
</head>
<body></body>
<script type="text/javascript">
var app = angular.module('peoplesearchApp',[]);
app.controller('peopleSearchCtrl',function($scope,$http){
$scope.textChanged = function() {
// obtain the list of user whose name have the given prefix
var searchUsers = ($scope.searchString) ? $scope.searchString.trim(): "";
$http.get('/findusers?q=' + searchUsers).success(function(data, status) {
$scope.users = data;
}).error(function(data, status) {
console.log("Error: could not retrieve users");
});
};
// make an initial call to retrieve all users
$scope.textChanged();
});
describe('search people app tests', function () {
var controller, httpBackend, scope;
// setup before each test run
beforeEach(module('peoplesearchApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
controller = _$controller_('peopleSearchCtrl', {$scope: scope});
}));
describe('only the users that have their names starting from the search query should be visible', function () {
it('should show all users for a blank query', function () {
httpBackend.when('GET', '/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
scope.textChanged();
httpBackend.flush();
expect(scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
});
it('should show only Rory for query=r', function () {
httpBackend.when('GET', '/findusers?q=')
.respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
scope.searchString = 'r';
httpBackend.when('GET', '/findusers?q=r')
.respond(['Rory']);
scope.textChanged();
httpBackend.flush();
expect(scope.users).toEqual(['Rory']);
});
});
})
</script>
</html>
希望能解决您的问题。
干杯!