node.js - mock - nock npm
Nock no intercepta la llamada API en la prueba de Redux (2)
Intento probar una llamada de API en una aplicación redux. El código prácticamente sigue el patrón descrito en la sección Creadores de acciones de Async de los documentos de redux:
http://redux.js.org/docs/recipes/WritingTests.html
La esencia de esto es que utilizas redux-mock-store para registrar y afirmar contra cualquier acción que se desencadene.
Esta es toda la prueba, usando nock para burlarse de la llamada api:
import React from ''React''
import ReactDOM from ''react-dom''
import expect from ''expect'';
import expectJSX from ''expect-jsx'';
import TestUtils from ''react-addons-test-utils''
import configureMockStore from ''redux-mock-store''
import thunk from ''redux-thunk''
import nock from ''nock''
expect.extend(expectJSX);
import * as types from ''../../constants/Actions''
describe(''Async Search Actions'', () => {
const thunkMiddleware = [ thunk ];
/* use redux-mock-store here */
const mockStore = configureMockStore(thunkMiddleware);
describe(''The fetchArtistData action creator should'', () => {
afterEach(() => {
nock.cleanAll()
})
it(''Should fire off a ARTIST action when fetch is done'', (done) => {
nock(''http://ws.audioscrobbler.com'')
.get(''/2.0/'')
.query({method: ''artist.search'', artist: ''ho'', api_key: ''abc123'', format: ''json'', limit: 5})
.reply(200,
{
fake: true
}
)
const expectedActions = [
{ type: types.ARTIST, artists: {
fake: true
}
}
];
let store = mockStore([], expectedActions, done);
store.dispatch(fetchArtist(''ho''))
});
});
});
Pero parece que se llama a la api real lastFm cuando se ejecuta la prueba ... se devuelven datos reales de lastFm en lugar de la respuesta falsa de nock.
Este es el creador de la acción en sí:
export function fetchArtist(search) {
return dispatch => {
return fetch(`http://ws.audioscrobbler.com/2.0/?method=artist.search&artist=${search}&api_key=abc123&format=json&limit=5`)
.then(handleErrors)
.then(response => response.json())
.then(json => { dispatch(ArtistData(searchTerm, json)) })
.catch(handleServerErrors)
}
}
La aserción falla porque la respuesta live lastFM no es la misma que la respuesta que espero según el objeto expectedActions
.
Intenté asignar el nock a una variable y cerrarla. El registro muestra esto:
Nock parece estar agregando el puerto 80 a la url, no estoy seguro de si esto está causando que la API real no se burle:
keyedInterceptors: Object{GET http://ws.audioscrobbler.com:80/2.0/?
method=artist.search&artist=john&api_key=abc123&format=json&limit=5
Alguna idea de lo que está mal aquí?
Necesita pasar solo la URL base a la función principal de nock
y separar la porción de ruta de URL en el método .get()
.
nock(''http://ws.audioscrobbler.com'')
.get(''/2.0/'')
.query({
method: ''artist.search'',
artist: ''bob'',
api_key: ''somekey123'',
format: ''json'',
limit: ''5''
})
.reply(200, {fake: true})
Pude obtener una respuesta falsa con el código anterior.
Para usar nock debes ejecutar tus pruebas en el nodo (usando Jest o mocha), nock anula el comportamiento del nodo http y por ese motivo solo funciona en el nodo y no en los navegadores (como PhantomJS).
Por ejemplo, el enlace que ha indicado utiliza Jest y las primeras líneas son explícitas sobre el entorno del nodo. Por lo tanto, nock funcionará como un encanto. http://redux.js.org/docs/recipes/WritingTests.html
Configurando
Recomendamos Jest como el motor de prueba. Tenga en cuenta que se ejecuta en un entorno de nodo, por lo que no tendrá acceso al DOM.
Como veo, puedes:
- ejecuta tus pruebas en un entorno de nodo
- o usa una biblioteca diferente para burlarse como fetch-mock