我有以下控制器EditMeetingCtrl.js
(function() {
'use strict';
angular
.module('myApp')
.controller('EditMeetingCtrl', EditMeetingCtrl);
EditMeetingCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$translate',
'meetingService', 'companyService', 'notificationService', 'meeting'];
function EditMeetingCtrl($rootScope, $scope, $state, $http, $translate, meetingService, companyService, notificationService, meeting) {
$scope.meeting = meeting;
$scope.companyId = $state.params.companyId;
$scope.save = save;
function save() {
$scope.buttonDisable = true;
meetingService.saveMeeting($state.params.companyId, $state.params.meetingId, $scope.meeting)
.success(function(meetingId) {
//more code
});
}
}
})();
EditMeetingCtrlSpec.js测试用例
describe('in EditMeetingCtrl', function () {
var companyService , meetingService ;
meetingId = 123321 ;
companyId = 456654 ;
meetingObj = {} ;
var fakeHttpPromise = {
success: function() {}
};
beforeEach(angular.mock.module('myApp'));
beforeEach(angular.mock.inject(function (_$httpBackend_, _companyService_ , _meetingService_) {
$httpBackend = _$httpBackend_;
companyService = _companyService_;
meetingService = _meetingService_ ;
}));
describe('EditMeetingCtrl.save()', function () {
var $rootScope, scope, $controller , $q ;
beforeEach(inject(function ($rootScope, $controller , _meetingService_ ) {
scope = $rootScope.$new();
createController = function() {
return $controller('EditMeetingCtrl', {
$scope: scope,
meeting : {} ,
meetingService : _meetingService_
});
};
var controller = new createController();
}));
it("should save the meeting object", function() {
spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise);
scope.save();
expect(meetingService.saveMeeting).toHaveBeenCalledWith( meetingId , companyId , meetingObj);
});
});
});
当尝试运行以下测试casse EditMeetingCtrlSpec.js时,我得到以下测试失败
PhantomJS 1.9.8 (Windows 8) EditMeetingCtrl Spying --> EditMeetingCtrl.save() should save the meeting FAILED
Expected spy saveMeeting to have been called with [ 123321, 456654, Object({ }) ] but actual calls were [ undef
ined, undefined, Object({ }) ].
因此,了解此问题的方式是,save()
方法的服务调用包含$state.params.companyId, $state.params.meetingId
个参数,并在调用服务调用时发送undefined
个值。因此我需要嘲笑$state.params
。不知道该怎么做。谁能指出我正确的方向?
迈克尔拉迪奥诺夫回答后的编辑
describe('EditMeetingCtrl.save()', function () {
var $rootScope, scope, $controller , $q , $state ;
beforeEach(inject(function ($rootScope, $controller , $state , _meetingService_ ) {
scope = $rootScope.$new();
createController = function() {
return $controller('EditMeetingCtrl', {
$scope: scope,
meeting : {} ,
meetingService : _meetingService_
});
};
var controller = new createController();
}));
it("should save the meeting", function() {
$state.params = { companyId: 123, meetingId: 567 };
spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise);
scope.save();
//expect(meetingService.saveMeeting).toHaveBeenCalledWith( meetingId , companyId , meetingObj);
});
});
我已经完成了上述操作,但是我收到以下错误:$ state未定义。
Firefox 38.0.0 (Windows 8.1) In EditMeetingCtrl EditMeetingCtrl.save() should save the meeting FAILED
TypeError: $state is undefined in C:/Users/sal/Documents/myApp/test/meeting/EditMe
etingCtrlSpec.js (line 80)
我认为这是因为我没有这样做 - >注入方法中的$state : state
,所以我也尝试过这样做但得到了同样的错误。我在这里失踪了什么?
答案 0 :(得分:19)
您可以模拟整个import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Trie<V> {
Entry<V> entry;
char key;
Map<Character, Trie<V>> children;
public Trie() {
this.children = new HashMap<Character, Trie<V>>(10);
entry = new Entry<V>();
}
/** non-public, used by _put() */
Trie(char key) {
this.children = new HashMap<Character, Trie<V>>(10);
this.key = key;
entry = new Entry<V>();
}
public void put(String key, V value) {
_put(new StringBuffer(key), new StringBuffer(""), value);
}
void _put(StringBuffer remainder, StringBuffer prefix, V value) {
if (remainder.length() > 0) {
char keyElement = remainder.charAt(0);
Trie<V> t = null;
try {
t = children.get(keyElement);
} catch (IndexOutOfBoundsException e) {
}
if (t == null) {
t = new Trie<V>(keyElement);
children.put(keyElement, t);
}
prefix.append(remainder.charAt(0));
t._put(remainder.deleteCharAt(0), prefix, value);
} else {
this.entry.value = value;
this.entry.prefix = prefix.toString();
}
}
/**
* Retrieves element from prefix table matching as a prefix to provided key.
* E.g. is key is "abcde" and prefix table has node "ab" then this call will
* return "ab"
*
* @param key
* a string which starts with prefix to be searched in the table
* (e.g. phone number)
* @return an Object assosiated with matching prefix (i.e if key is a phone
* number it may return a corresponding country name)
*/
public V get(String key) {
return _get(new StringBuffer(key), 0);
}
/**
* Returns true if key has matching prefix in the table
*/
public boolean hasPrefix(String key) {
return ((this.get(key) != null) ? true : false);
}
V _get(StringBuffer key, int level) {
if (key.length() > 0) {
Trie<V> t = children.get(key.charAt(0));
if (t != null) {
V result = t._get(key.deleteCharAt(0), ++level);
return result == null ? entry.value : result;
} else {
return (level > 0) ? entry.value : null;
}
} else {
return entry.value;
}
}
@Override
public String toString() {
Iterator<Character> it = children.keySet().iterator();
StringBuffer childs = new StringBuffer();
while (it.hasNext()) {
Character key = it.next();
childs.append(String.format("\n%s\n",
// adding a tab to the beginning of every line to create a visual tree
String.format("%s: %s", key, children.get(key)).toString().replaceAll("(?m)(^)", "\t")));
}
return String.format("Trie [entry=%s, children=%s]", entry, childs);
}
static public class Entry<V> {
String prefix;
V value;
public Entry() {
}
public Entry(String p, V v) {
prefix = p;
value = v;
}
public String prefix() {
return prefix;
}
public V value() {
return value;
}
@Override
public String toString() {
return "Entry [prefix=" + prefix + ", value=" + value + "]";
}
}
}
提供程序,然后在调用$state
之前准确指定您希望在params
属性中包含哪些值:
save