Vue-test-utils Respuesta de la captura de mock de otro componente
Estoy tratando de establecer pruebas de unidad usando vue-test-utils
y jest
algunos Vue components that retrieve responses from another Vue component (ApiCalls.vue) that is in charge of making calls to a remote API using fetch()
.
El componente que hace llamadas API devuelve objetos de este tipo:
{
status: ,
body:
}
Componente a ser probado (respecto general)MyComponent.vue
)
import ApiCalls from './ApiCalls.vue';
export default {
data() {
return {
resultsFromAPI: null
}
},
mounted() {
this.getSomeData();
},
methods: {
async getSomeData() {
const APIResponse = await ApiCalls.data().getSomeData();
if (APIResponse.status === 200) {
this.resultsFromAPI = APIResponse.body;
}
}
}
}
Resumen de las especificaciones de prueba :
import { shallowMount } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';
const wrapper = shallowMount(MyComponent);
test('check data from API', () => {
expect(wrapper.vm.resultsFromAPI).toBe();
});
Traté de burlar la función getSomeData
así:
wrapper.vm.getSomeData = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({status: 200, body: { result: 'blabla' }),
})
);
O
const getSomeData = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({status: 200, body: { result: 'blabla' }),
})
);
Pero no funciona y no puedo encontrar ninguna pista en el vue-test-utils ni jest config... Cualquier ayuda sería apreciada.
Pregunta hecha hace 3 años, 4 meses, 27 días - Por codealchemy
3 Respuestas:
-
En primer lugar, nunca deberías llamar
data()
funciona en un constructor Vue. Quiero decir, puedes hacerlo solo por patadas, pero ya sabes lo que va a volver, ¿verdad? No es ningún misterio. El "magic" es el constructor crea propiedades reactivas en la instancia Vue devuelta para cada miembro dedata()
's result with a value other thanundefined
Ahora, llegando al verdadero problema con sus intentos de burla: parece que ha entendido mal el propósito de burlarse y, por lo tanto, el propósito de la prueba de unidad. Mocking está reemplazando un sistema externo (a su componente) con algo que siempre se comporta como que se espera que el sistema externo se comporta. Porque sólo debe probar la unidad actual (componente) y nada más. Su prueba no debe depender de si la máquina que ejecuta la prueba tiene acceso a la API, si la API está actualmente baja, etc...
Pero... no se burlan nunca del contenido del componente que está siendo probado!
Si haces eso creas la posibilidad de que tu componente probado se rompa mientras la prueba pasa, ya que el método roto es reemplazado en la prueba con una maqueta sólida. Usted desea una prueba que ejecuta el código real dentro de su método, que falla cuando el componente falla y que pasa cuando el componente se comporta como se espera.
Usted debe probar si el componente genera la salida esperada para todas las entradas posibles.
En tu caso, deberías burlarte.
ApiCalls
con algo comportarse como usted esperaApiCalls
para comportarte, y básicamente hay dos cosas que debes probar:ApiCalls.getSomeData
se llama una vez (no menos, no más), cuando el componente actual se ha montado (y que se llamó con los parámetros correctos)- el componente
.resultsFromAPI
son pobladas con los datos devueltos cuando el estado de respuesta es200
y permanecernull
de lo contrario.
Su componente no debe importar lo que
ApiCalls
Lo es. En otras palabras,ApiCalls
Debería ser una burla. Podría ser algo que en realidad llama al backend o un backend mock. Todo lo que importa es cómo tu componente react a diferentes respuestas de cualquier cosaApiCalls
Los métodos regresan.Una última cosa que podrías probar es lo que pasa cuando
ApiCalls
no está disponible, si usted piensa que es una posibilidad real (o lo que sucede si nunca resuelve - se detiene). Estos son casos de borde y no normalmente cubiertos, a menos que haya una solicitud específica del cliente la aplicación debe recuperarse de errores estructurales (es un caso raro).Para resumir, nunca escriba una prueba que podría pasar cuando el componente real está roto. Es una de esas cosas que podrían hacer que te despidan en el lugar (es una metáfora - reemplazar por lo que puedas perder en caso de fracaso: clientes, clientes, vidas, cuentas, reputación, etc...), si algo significativo realmente depende de si tu componente cumple o no como se esperaba. Debido a que no sólo la prueba que escribió no pudo capturar el error, pero en realidad mintió sobre haber probado el componente (que nunca hace - que prueba el componente mock). Así que da un falso y peligroso sentido de seguridad.
Métodos de uso descritos en esta respuesta para burlarse
ApiCalls
Métodos.Nota: en toda justicia, podría haber marcado su pregunta como duplicado de lo anterior y de muchos otros. Esto se ha preguntado antes.
Sin embargo, elegí publicar esta larga advertencia como respuesta (en la esperanza de que usted y tal vez otros lo encuentren útil) y esbozar los peligros de no burlarse de lo que debe ser burlado y de no probar correctamente, ya que creo que es un gran problema con cómo los UT son a menudo escritos.
Algunas de las culpas por este tipo de errores (y su peligro) también radican en que los UT se hacen obligatorios hoy en día, mientras que muy pocas empresas de codificación ponen cualquier esfuerzo en la enseñanza de principios de prueba.Respondida el Dec 18, 2020 a las 09:22 - por codervoyager
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás enfrentando es que estás intentando simular la respuesta de un método asíncrono dentro de tus pruebas, pero el enfoque que estás utilizando no es correcto. En lugar de tratar de burlar la función
getSomeData
directamente, debes modificar la forma en que el componente llama aApiCalls
.Dado que
ApiCalls
es responsable de hacer llamadas a la API y retornar la respuesta en un objeto con la estructura{ status: <status>, body: <body> }
, puedes crear un mock deApiCalls
y hacer que retorne la respuesta esperada al ser llamado porMyComponent
.A continuación te muestro cómo podrías modificar tus pruebas para lograr esto:
js import { shallowMount } from '@vue/test-utils'; import MyComponent from './MyComponent.vue'; // Mock de ApiCalls jest.mock('./ApiCalls.vue', () => ({ data() { return { async getSomeData() { return { status: 200, body: { result: 'blabla' } }; } }; } })); test('check data from API', async () => { const wrapper = shallowMount(MyComponent); // Espera a que se resuelva la llamada a la API await wrapper.vm.getSomeData(); // Verifica que los resultados de la API sean los esperados expect(wrapper.vm.resultsFromAPI).toEqual({ result: 'blabla' }); });
En este nuevo enfoque, en lugar de burlar la función
getSomeData
, hemos creado un mock deApiCalls
que devuelve la respuesta esperada. Luego, en la prueba, primero invocamosgetSomeData
enMyComponent
y esperamos a que se resuelva antes de verificar los resultados.Espero que esta solución te sea útil y te ayude a resolver tu problema. ¡Déjame saber si necesitas más ayuda!
Respondida el Dec 19, 2020 a las 09:25 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Simula la llamada a la API en el componente ApiCalls.vue
Para simular la llamada a la API en ApiCalls.vue, puedes usar la función
mockImplementation
de Jest para interceptar la llamadagetSomeData
en el métodomounted
:javascript // En MyComponent.test.js import { shallowMount } from '@vue/test-utils'; import MyComponent from './MyComponent.vue'; const wrapper = shallowMount(MyComponent); // Simula la llamada a getSomeData en ApiCalls.vue jest.spyOn(wrapper.vm.$refs.apiCalls, 'getSomeData').mockImplementation(() => Promise.resolve({ status: 200, body: { result: 'blabla' }, }) ); test('check data from API', () => { expect(wrapper.vm.resultsFromAPI).toBe({ result: 'blabla' }); });
Explicación:
mockImplementation
reemplaza la implementación original degetSomeData
con la función proporcionada. En la función proporcionada, devolvemos la respuesta simulada con unstatus
de 200 y un cuerpo que contiene el resultado esperado. Luego, verificamos siresultsFromAPI
enMyComponent
contiene el resultado simulado.Referencias
Simulación de funciones con Jest * Usando simulacros en Vue.js
Respondida el Dec 19, 2020 a las 09:27 - por Gemini
Votos positivos: 0 | Votos negativos: 0