Back to Repositories

Testing Dev Server Proxy Configuration in vue-cli

This test suite validates proxy configuration functionality in Vue CLI’s development server. It tests both single and multiple proxy setups, ensuring proper request forwarding and API integration during local development.

Test Coverage Overview

The test suite provides comprehensive coverage of Vue CLI’s proxy configuration capabilities.

Key areas tested include:
  • Single proxy configuration with direct URL forwarding
  • Multiple proxy setup with path-based routing
  • Request method handling (GET and POST)
  • Path rewriting functionality

Implementation Analysis

The testing approach utilizes Jest’s async/await patterns for handling HTTP requests and mock servers. The implementation leverages mock JSON servers to simulate API endpoints, with separate servers running on different ports to test multi-proxy scenarios.

Technical patterns include:
  • Dynamic project creation using CLI test utilities
  • Custom assertion functions for validating proxy behavior
  • Configuration file manipulation for different proxy setups

Technical Details

Testing infrastructure includes:
  • Jest as the primary testing framework
  • node-fetch for HTTP requests
  • @vue/cli-test-utils for project setup
  • Mock JSON servers for API simulation
  • Puppeteer integration capability
Configuration includes timeout settings and server cleanup in afterAll hooks.

Best Practices Demonstrated

The test suite exemplifies several testing best practices in the Vue ecosystem.

Notable practices include:
  • Proper test isolation with setup/teardown
  • Async/await usage for clear async flow
  • Modular test configuration
  • Comprehensive error cases coverage
  • Clean separation of concerns between test utilities and assertions

vuejs/vue-cli

packages/@vue/cli-service/__tests__/proxy.spec.js

            
jest.setTimeout(30000)

const fetch = require('node-fetch')
const { defaultPreset } = require('@vue/cli/lib/options')
const create = require('@vue/cli-test-utils/createTestProject')
const serve = require('@vue/cli-test-utils/serveWithPuppeteer')
const createJSONServer = require('@vue/cli-test-utils/createJSONServer')

let mockServer1
let mockServer2

beforeAll(done => {
  mockServer1 = createJSONServer({
    'posts': [
      { 'id': 1, 'title': 'server-one', 'author': 'typicode' }
    ]
  }).listen(3000, () => {
    mockServer2 = createJSONServer({
      'posts': [
        { 'id': 1, 'title': 'server-two', 'author': 'typicode' }
      ]
    }).listen(3001, done)
  })
})

afterAll(() => {
  mockServer1.close()
  mockServer2.close()
})

let newId = 1
async function assertProxy (url, title) {
  const res = await fetch(`${url}posts/1`).then(result => result.json())
  expect(res.title).toBe(title)

  // POST
  newId++
  await fetch(`${url}posts`, {
    method: 'POST',
    body: JSON.stringify({
      id: newId,
      title: 'new',
      author: 'test'
    }),
    headers: { 'Content-Type': 'application/json' }
  })

  const newPost = await fetch(`${url}posts/${newId}`).then(result => result.json())
  expect(newPost.title).toBe('new')
}

test('serve with single proxy', async () => {
  const project = await create('single-proxy', defaultPreset)

  await project.write('vue.config.js', `
    module.exports = {
      devServer: {
        proxy: 'http://localhost:3000'
      }
    }
  `)

  await serve(
    () => project.run('vue-cli-service serve'),
    ({ url }) => assertProxy(url, 'server-one'),
    true /* no need for puppeteer */
  )
})

test('serve with multi proxies', async () => {
  const project = await create('multi-proxy', defaultPreset)

  await project.write('vue.config.js', `
    module.exports = {
      devServer: {
        proxy: {
          '/one': {
            target: 'http://localhost:3000',
            pathRewrite: {
              '^/one': ''
            }
          },
          '/two': {
            target: 'http://localhost:3001',
            pathRewrite: {
              '^/two': ''
            }
          }
        }
      }
    }
  `)

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ url }) => {
      await assertProxy(`${url}one/`, 'server-one')
      await assertProxy(`${url}two/`, 'server-two')
    },
    true /* no need for puppeteer */
  )
})