#vue.js #jestjs #vue-test-utils #vuejs3 #vue-composition-api
#vue.js #jestjs #vue-test-utils #vuejs3 #vue-composition-api
Вопрос:
Я использую API-интерфейс Vue composition и импортирую модуль в однофайловый компонент. Я присваиваю возвращаемое значение модуля переменной в методе setup, а затем возвращаю значение, чтобы шаблон мог использовать переменную. Компонент отображает один ItemComponent для каждого элемента, полученного из импортированного модуля.
Фактическое приложение работает нормально и отображает правильное количество элементов. С другой стороны, мой тест не выполняется, и, похоже, функция mockReturnValue не вызывается.
Однофайловый код компонента
<template>
<ul class="ItemList">
<ItemComponent
v-for="item in items"
:key="item.id"
:item="item" />
</ul>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import ItemComponent from '@/components/ItemComponent.vue';
import module from '@/module';
export default defineComponent({
components: {
ItemComponent,
},
setup() {
const { items } = module.property // note destructuring here
console.log(items);
return { items };
},
});
</script>
mock-module.ts
export const property = {
items: jest.fn(),
};
(макет) index.ts
import {module} from './modules/mock-module';
export default {module}
Тестовый файл
import module from '@/modules/__mocks__/index.ts';
jest.mock('../../../src/modules/index.ts');
it('should render an ItemComponent for each item', () => {
module.property.items.mockReturnValue([{}, {}, {}]); // Doesn't seem to get invoked?
const wrapper = mount(MyComponent, { shallow: true });
expect(wrapper.findAllComponents('item-component-stub').length)
.toBe(3);
});
Результат
Тест завершается с ошибкой и находит 0 элементов, и когда я console.log(items)
из однофайлового компонента получаю следующее:
[Function: mockConstructor] {
_isMockFunction: true,
getMockImplementation: [Function (anonymous)],
mock: [Getter/Setter],
mockClear: [Function (anonymous)],
mockReset: [Function (anonymous)],
mockRestore: [Function (anonymous)],
mockReturnValueOnce: [Function (anonymous)],
mockResolvedValueOnce: [Function (anonymous)],
mockRejectedValueOnce: [Function (anonymous)],
mockReturnValue: [Function (anonymous)],
mockResolvedValue: [Function (anonymous)],
mockRejectedValue: [Function (anonymous)],
mockImplementationOnce: [Function (anonymous)],
mockImplementation: [Function (anonymous)],
mockReturnThis: [Function (anonymous)],
mockName: [Function (anonymous)],
getMockName: [Function (anonymous)]
}
Это указывает (для меня), что тест использует макет файла, но по какой-то причине не вызывает .mockReturnValue()
вызов. Если я просто изменю фиктивную зависимость от jest.fn() на некоторое фактическое значение, консоль.оператор log возвращает это значение. Конечно, я не хочу этого делать, так как мне нужно иметь возможность устанавливать разные возвращаемые значения в разных тестах.
Чего я ожидаю, я ожидал бы, когда я вызываю module.property.items.mockReturnValue([{}, {}, {}])
эту консоль.log напечатал бы массив с тремя пустыми объектами, и тест прошел бы с отображением 3/3 ItemComponents.
Ответ №1:
items: jest.fn()
создает items
шпиона. Вывод на консоль — это тот, который следует ожидать, он показывает, что это функция. mockReturnValue
не имеет шансов не быть вызванным, если тест продолжается. Его результат можно рассматривать как:
module.property.items.mockReturnValue([{}, {}, {}])
expect(module.property.items()).toEqual([{}, {}, {}])
Поскольку items
предполагается, что это массив, а не функция, его неправильно подделали. Обычно это делается путем прямого изменения свойств без jest.mock
выполнения в этом модуле:
module.property = [{}, {}, {}]
Дополнительно должно быть гарантировано, что измененное значение не повлияет на другие тесты, например, выполнив это, jest.isolateModules
чтобы повторно импортировать иерархию затронутых модулей.
Это также можно сделать с помощью Jest spies, но для легкого доступа к ней требуется сохранить ссылку на функцию getter:
export const property = {
items: null,
};
export const mockPropertyItems = jest.spyOn(property, 'items', 'get');
И используется как:
module.mockPropertyItems.mockReturnValue([{}, {}, {}])
expect(module.property.items).toEqual([{}, {}, {}])
Также импорт напрямую из __mocks__
неверен, издевательский модуль должен быть импортирован из его обычного местоположения.