query - angularjs versions
Probando $ servicios de recursos en AngularJS (2)
Intento comenzar a escribir pruebas unitarias para mi aplicación angular y llegar a un bloque de detención bastante rápido ya que no estoy seguro de cómo exactamente burlarme de mi servicio de forma comprobable.
¿Hay alguna manera de burlarse de la llamada REST? De lo contrario, parece que necesito reflejar todo lo que está dentro de mi servicio en mis pruebas, lo cual no me parece correcto, pero soy bastante nuevo para probar la escritura, así que tal vez así es como se supone para ser logrado. Cualquier ayuda sería muy apreciada.
Mi servicio es el siguiente:
angular.module(''resources.users'', [''ngResource''])
.factory(''User'', function($resource) {
var resource = $resource(''/api/index.php/users/:username'', {}, {
''update'': {method: ''PUT''}
});
resource.getUser = function(username, successCb) {
return resource.query({username: username}, successCb);
};
return resource;
});
Mi prueba consiste hasta ahora de:
describe(''User'', function() {
var mockUserResource;
beforeEach(module(''resources.users''));
beforeEach(function() {
mockUserResource = sinon.stub({
getUser: function(username) {
mockUserResource.query({username: username});
},
query: function() {}
});
module(function($provide) {
$provide.value(''User'', mockUserResource);
})
});
describe(''getUser'', function() {
it(''should call getUser with username'', inject(function(User) {
User.getUser(''test'');
expect(mockUserResource.query.args[0][0]).toEqual({username: ''test''});
}));
})
});
Puede simular las solicitudes hechas por ngResource de esta manera:
describe(''User'', function () {
var mockUserResource, $httpBackend;
beforeEach(angular.mock.module(''myApp''));
beforeEach(function () {
angular.mock.inject(function ($injector) {
$httpBackend = $injector.get(''$httpBackend'');
mockUserResource = $injector.get(''User'');
})
});
describe(''getUser'', function () {
it(''should call getUser with username'', inject(function (User) {
$httpBackend.expectGET(''/api/index.php/users/test'')
.respond([{
username: ''test''
}]);
var result = mockUserResource.getUser(''test'');
$httpBackend.flush();
expect(result[0].username).toEqual(''test'');
}));
});
});
La respuesta de zsong me ayudó mucho a entender esto, pero me gustaría ampliar cómo funciona. En caso de que se edite, vuelvo a enumerar el código aquí:
describe(''User'', function () {
var mockUserResource, $httpBackend;
beforeEach(angular.mock.module(''myApp''));
beforeEach(function () {
angular.mock.inject(function ($injector) {
$httpBackend = $injector.get(''$httpBackend'');
mockUserResource = $injector.get(''User'');
})
});
describe(''getUser'', function () {
it(''should call getUser with username'', inject(function (User) {
$httpBackend.expectGET(''/api/index.php/users/test'')
.respond([{
username: ''test''
}]);
var result = mockUserResource.getUser(''test'');
$httpBackend.flush();
expect(result[0].username).toEqual(''test'');
}));
});
});
¿Que está pasando aqui?
1
beforeEach(angular.mock.module(''myApp''));
Le decimos al inyector angular ( $injector
y angular.mock.inject
) que inyecte los elementos definidos en el módulo myApp
. Puede pensar que define una dependencia de módulo sin un módulo dependiente. Compare con cómo las cosas definidas en el módulo myApp
pueden ser inyectadas en, digamos, un controlador en un angular.module(''myOtherApp'', [''myApp''])
.
2
beforeEach(function () {
angular.mock.inject(function ($injector) {
$httpBackend = $injector.get(''$httpBackend'');
mockUserResource = $injector.get(''User'');
})
});
Antes de cada especificación, ejecute la function ($injector)
con las dependencias inyectadas. En este caso, la dependencia ( $injector
) se resuelve implícitamente del nombre del parámetro. Una variante funcionalmente equivalente de este fragmento es
beforeEach(function () {
angular.mock.inject([''$httpBackend'', ''User'', function ($httpB, User) {
$httpBackend = $httpB;
mockUserResource = User;
}]);
});
Aquí, en cambio, hemos declarado las dependencias explícitamente, y podemos usar libremente los nombres de parámetros que deseamos.
3
it(''should call getUser with username'', inject(function (User) {
De nuevo, la función de prueba se inyecta con el servicio de User
resuelto implícitamente como un parámetro, aunque en realidad no se utiliza.
Tenga en cuenta que esta vez no hay función de envoltura alrededor de la llamada de inject
. inject
invoca la función transmitida inmediatamente si una especificación se está ejecutando actualmente, pero de lo contrario devuelve una función de envoltura (consulte los angular.mock.inject inyección y el código fuente ), por lo que en realidad no necesitamos la función de envoltura. Por lo tanto, podríamos haber escrito beforeEach
fragmento beforeEach
esta manera:
beforeEach(angular.mock.inject(function ($injector) {
$httpBackend = $injector.get(''$httpBackend'');
mockUserResource = $injector.get(''User'');
}));