Если вам нравится Vue.js тогда вы, наверное, уже знаете, что Vuex является. Это государственная структура управления и библиотека для приложений Vue.js, которая вдохновлена поток/redux-подобной архитектуре.
Библиотека разработана и поддерживается командой разработки Vue.js, что означает, что это официальная рекомендованная государственная библиотека управления для структуры. Больше никаких доспехов государственных рамок управления!
Этот пост собирается инкапсулировать методику, которую я столкнулся с тем, что позволяет легко писать тесты вокруг вашего магазина Vuex, что приводит к гораздо менее хрупким тестам, чем единица тестирования отдельных движущихся частей индивидуально.
Vuex состоит из многочисленных основных концепций. Действия, мутации и геттерс – главные движущиеся части. Поскольку они все написаны как простые функции JavaScript, поэтому все они могут быть легко протестированы в изоляции.
Вопрос с таким подходом, хотя это то, что это приводит к хрупким тестам, а иногда и ложные позитивы. Например, для удаления тестирования действия мы можем проверить, что он в конечном итоге совершает определенную мутацию, с определенными ожидаемыми параметрами. Мы могли бы довольно легко использовать Jest сделать это.
Проблема, однако, это произойдет, если бы мы изменили имя одного из наших функций действий Vuex? Во-первых, наш тест не сможет запустить, потому что он больше не импортирует/ссылки на функцию, которая существует. Поскольку наш тест напрямую импортируют функцию действий, мы бы просто переименули функцию вызова, чтобы пройти тест.
Однако в рамках нашего фактического кода Vue Component мы будем делать Это $ Store.dispatch («OldactionActionName») Для того, чтобы отправить нашему действия, не непосредственно импортируя функцию действия. Поэтому, если у нас нет адекватного конца для окончания тестирования в нашей заявке, мы могли бы довольно легко оказаться в сценарии, в котором мы проходили модульные тесты, но приложение, которое не работает, потому что мы все еще отправляем старое действие!
К счастью, хотя удивительная команда по развитию Vuue, которая также находятся за официальной библиотекой по тестированию подразделения Vuue (которая также использует шутку на пути) – Vue Test Utils – Дали нам простое решение для этой проблемы. Решение, поверьте в этом или нет, это просто облегчить тестирование нашего магазина Vuex в целом, а не отдельных винтиков.
Ниже приведена прохождение с примером Pseud-ish Code, смоделированного на том, как мне удалось проверить свой магазин, не запускав в любую из этих проблем.
В этом случае мы собираемся проверить наш конец магазина до конца, действия, мутации, GetTers, вы называете его, все в одном тесте. Я видел некоторые утверждения, что это тест интеграции, однако, поскольку все внешние сотрудники все еще должны быть издеваться, я бы поспорил, что это просто немного более крупный тест на единицу.
Сценарий – подобный Instagram потенциал. У меня есть loadposts Действие в ходе постов ломтики моего магазина Vuex, который использует Axios Чтобы сделать асинхронный удаленный вызов на API для извлечения этих постов, а затем поместить их в глобальное состояние Vuex приложения.
Начнем с определения нашего магазина Vuex:
import Vue from "vue";
import Vuex from "vuex";
import posts from "./modules/posts";
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
posts
},
});
Далее мы определяем, что наши посты Vuex State Slice/модуль выглядит как:
import Vue from "vue";
import axios from "axios";
const state = () => ({
posts: [],
});
const mutations = {
SET_POSTS(state, posts) {
state.posts = posts;
},
};
const actions = {
loadPosts({ commit }) {
axios
.get("/api/posts/")
.then(function(response) {
commit("SET_POSTS", response.data);
})
.catch(function(error) {
console.log(error);
});
},
};
const getters = {
getPosts: (state) => {
return state.posts;
}
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
Здесь мы храним список постов как часть нашего государства. У нас есть наш loadposts действие, которое вызывает вызов Axios. У нас есть наш Set_posts Мутация, которая меняет нашу ценность Сообщения в нашем глобальном штате и, наконец, у нас есть Getter называется GetPosts что мы можем использовать для получения значения Сообщения из нашего государства.
Теперь, чтобы проверить наше государство, это просто. Мы хотим отправить loadposts Действие в наш магазин, а затем утверждает, что ожидаемое значение, очевидно, хранится в нашем магазине. Просто, верно? Для этого мы должны коснуться всех движущихся частей нашего магазина Vuex в тесте.
import Vuex from "vuex";
import { createLocalVue } from "@vue/test-utils";
import createStoreConfig from "./__mocks__/storeConfig";
import mockPosts from "./__mocks__/posts.json";
let store;
beforeEach(() => {
createLocalVue().use(Vuex);
const storeConfig = createStoreConfig();
store = new Vuex.Store(storeConfig);
});
import posts from "../../modules/posts";
export default function createStoreConfig() {
return {
modules: {
posts,
},
};
}
Здесь мы используем Createlocalvue Класс предоставлен нам Vue Test Utils для создания класса Vue для нас, чтобы добавить наши компоненты, плагины (Vuex в этом случае), чтобы использовать в рамках нашего теста без загрязнения глобального класса Vue. Мы поставили это в нашу Rebedeach Что гарантирует, что каждый тест магазина не только использует отдельный экземпляр Vue, но также начинается свежий с пустым магазином.
import Vuex from "vuex";
import { createLocalVue } from "@vue/test-utils";
import createStoreConfig from "./__mocks__/storeConfig";
import mockPosts from "./__mocks__/posts.json";
jest.mock("axios", () => ({
get: jest.fn(() => Promise.resolve({ data: mockPosts })),
}));
let store;
beforeEach(() => {
createLocalVue().use(Vuex);
const storeConfig = createStoreConfig();
store = new Vuex.Store(storeConfig);
});
describe("Post Store Tests", () => {
it("loads posts and updates them in state", async () => {
await store.dispatch("posts/loadPosts");
expect(store.getters["posts/getPosts"]).toEqual(mockPosts);
});
});
Для того, чтобы написать наш тест, нам нужно издеваться на нашу вызов AXIOS API. Мы можем использовать jest, чтобы сделать это. В этом случае я решил хранить аналогичное представление JSON данных, которые вернулись с реального API в файле JSON, однако в теории вы можете использовать все, что вы хотите, пока оно в конечном итоге сохраняется в состоянии Отказ Причина, по которой мы хотим издеваться на наших вызовов Axio, заключается в том, чтобы предотвратить пробежку наших модульных тестов, и для того, чтобы убедиться, что у нас нет внешних зависимостей, которые могут привести к очевидным проблемам (например, если API когда-либо снизился, наши тесты потерпели неудачу, хотя Наш код в теории работает нормально).
Сам тест прост. Мы используем объект магазина, который мы создаем перед запуском каждого теста, чтобы отправить действие, которое мы хотим проверить. Если это действие работает правильно, то он должен вызвать мутацию тоже под капотом. Затем мы используем наш Getter в магазине, чтобы утверждать, что данные в штате мутировали как ожидалось. Сделано и посыпается!
Одно из великих вещей о тестировании нашего магазина Vuex Этот способ заключается в том, что в нашем тесте мы называем store.dispatch ("посты/loadposts") Точно так же, как наши настоящие умные компоненты. Мы больше не импортируем loadposts Функция напрямую и проверяя ее в разных обстоятельствах, чтобы использовать наше фактическое приложение. Итак, если наши тестовые перерывы, то наше приложение, безусловно, также сломано!
Если какая-либо часть путешествия Vuex, чтобы мутировать элемент государственных перерывов, тест узнает об этом. Основной недостаток этого подхода по сравнению с тем более гранулированным подходом, состоит в том, что будет сложнее отлаживать именно то, какую движущуюся часть пошло не так.
Надеюсь, это поможет … И как всегда, спасибо за чтение!
PS: Если вам понравилось сообщение, не забывайте, что вы можете найти больше своей работы прямо в моем блоге на http://karam.io Действительно
Оригинал: “https://dev.to/karam/easily-test-your-vuex-store-using-vue-test-utils-3172”