You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用VueJS、TypeScript和Jest测试下拉列表Web组件内容

Got it, let's walk through how to test this scenario effectively. You need to confirm that when your SearchBar component's created() hook fires, the dropdown web component gets populated with options fetched via the Vuex store's HTTP action. Since you're using Vue + TypeScript + Jest, here's a tailored approach with code examples and explanations:

Step 1: Set Up Dependencies & Mocks

First, we'll mock the Vuex store (including typed store support for TypeScript) and the dropdown web component—we don't need to test the dropdown's internal logic, just that it receives the correct props.

import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import SearchBar from '@/components/SearchBar.vue';
import { Actions } from '@/store/actions'; // Adjust the import path to match your project

// Initialize local Vue instance for testing
const localVue = createLocalVue();
localVue.use(Vuex);

// Mock the dropdown web component to track prop updates
jest.mock('@/components/dropdown-web-component.vue', () => ({
  name: 'dropdown-web-component',
  props: ['label', 'options'],
  template: '<div></div>' // Simple placeholder template
}));

Step 2: Write the Test Suite

We'll create a mock store, simulate the async HTTP action, and verify the dropdown receives the right options after the created() hook runs.

describe('SearchBar Component', () => {
  let store: Vuex.Store<any>;
  let mockActions: Record<string, jest.Mock>;

  beforeEach(() => {
    // Mock the GetApplications action to resolve with sample application data
    mockActions = {
      [Actions.GetApplications]: jest.fn().mockResolvedValue([
        { id: 1, name: 'Inventory App' },
        { id: 2, name: 'CRM Tool' },
        { id: 3, name: 'Analytics Dashboard' }
      ])
    };

    // Create mock store with initial empty state and mocked actions
    store = new Vuex.Store({
      state: {
        applications: [] // Starts empty, will be populated by the action
      },
      actions: mockActions
    });

    // Add typed store mock to satisfy TypeScript type checks
    (store as any).$typedStore = store;
  });

  it('populates dropdown with applications from Vuex store after created hook triggers', async () => {
    // Mount the SearchBar component with our mock store
    const wrapper = shallowMount(SearchBar, {
      localVue,
      store
    });

    // Wait for async action to resolve and component to update
    await wrapper.vm.$nextTick();
    await Promise.resolve(); // Ensures all pending promises from the action complete

    // Get reference to the mocked dropdown component
    const dropdownComponent = wrapper.findComponent({ name: 'dropdown-web-component' });

    // Verify the action was dispatched correctly
    expect(mockActions[Actions.GetApplications]).toHaveBeenCalledTimes(1);

    // Verify the dropdown received the correct options from the store
    expect(dropdownComponent.props('options')).toEqual([
      { id: 1, name: 'Inventory App' },
      { id: 2, name: 'CRM Tool' },
      { id: 3, name: 'Analytics Dashboard' }
    ]);
  });
});

Key Explanations

  • Mocking the Web Component: We replace the actual dropdown with a simple mock to focus on prop validation, not the dropdown's own functionality.
  • Handling Async Logic: The GetApplications action is async, so we use await $nextTick() and await Promise.resolve() to ensure all async operations finish before making assertions.
  • Typed Store Support: We add $typedStore to the mock store to avoid TypeScript errors during testing, matching your component's usage.
  • Double Assertion: We check both that the action was dispatched (to confirm the created() hook worked) and that the dropdown received the correct options (the end goal).

Bonus: Handling Realistic Vuex Mutations

If your actual Vuex action uses a mutation to update the applications state (instead of directly modifying it), adjust the mock action to trigger that mutation:

mockActions = {
  [Actions.GetApplications]: jest.fn().mockImplementation(async ({ commit }) => {
    const mockApps = [{ id: 1, name: 'Inventory App' }];
    commit('SetApplications', mockApps); // Match your actual mutation name
    return mockApps;
  })
};

// Update the mock store to include the mutation
store = new Vuex.Store({
  state: { applications: [] },
  actions: mockActions,
  mutations: {
    SetApplications: (state, apps) => { state.applications = apps; }
  }
});

This makes the test more aligned with how your production store works.

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 16:12:54