Nuxt Ava端到端测试存储配置

时间:2018-10-10 16:58:31

标签: vuejs2 vuex nuxt.js ava

给出使用Ava的示例正式Nuxt端到端测试example

import test from 'ava'
import { Nuxt, Builder } from 'nuxt'
import { resolve } from 'path'

// We keep a reference to Nuxt so we can close
// the server at the end of the test
let nuxt = null

// Init Nuxt.js and start listening on localhost:4000
test.before('Init Nuxt.js', async t => {
  const rootDir = resolve(__dirname, '..')
  let config = {}
  try { config = require(resolve(rootDir, 'nuxt.config.js')) } catch (e) {}
  config.rootDir = rootDir // project folder
  config.dev = false // production build
  config.mode = 'universal' // Isomorphic application
  nuxt = new Nuxt(config)
  await new Builder(nuxt).build()
  nuxt.listen(4000, 'localhost')
})

// Example of testing only generated html
test('Route / exits and render HTML', async t => {
  let context = {}
  const { html } = await nuxt.renderRoute('/', context)
  t.true(html.includes('<h1 class="red">Hello world!</h1>'))
})

// Close the Nuxt server
test.after('Closing server', t => {
  nuxt.close()
})

如何使用NuxtBuilder来配置/访问应用程序Vuex store? Vuex商店示例如下所示:

import Vuex from "vuex";

const createStore = () => {
  return new Vuex.Store({
    state: () => ({
      todo: null
    }),
    mutations: {
      receiveTodo(state, todo) {
        state.todo = todo;
      }
    },
    actions: {
      async nuxtServerInit({ commit }, { app }) {
        console.log(app);
        const todo = await app.$axios.$get(
          "https://jsonplaceholder.typicode.com/todos/1"
        );
        commit("receiveTodo", todo);
      }
    }
  });
};

export default createStore;

当前尝试运行提供的Ava测试,导致尝试访问@nuxtjs/axios方法$ get:

时出错。
TypeError {
  message: 'Cannot read property \'$get\' of undefined',
}

我可以在Vuex存储方法$get中模拟$axios上的app甚至nuxtServerInit上可用的app,我只需要了解如何访问{{1 }}。

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

刚刚遇到这个,挖了这么多教程,我拼凑了一个解决方案。

在以编程方式使用它时,您实际上已将 vuex 存储导入 Nuxt。这是通过以下方式完成的:

  1. 导入 Nuxt 的配置文件
  2. 添加到配置以关闭所有其他功能,但启用商店
  3. 加载 Nuxt 实例并继续您的测试

这是一个工作代码(假设您的 ava 和依赖项已设置)

// For more info on why this works, check this aweomse guide by this post in getting this working
// https://medium.com/@brandonaaskov/how-to-test-nuxt-stores-with-jest-9a5d55d54b28
import test from 'ava'
import jsdom from 'jsdom'
import { Nuxt, Builder } from 'nuxt'
import nuxtConfig from '../nuxt.config' // your nuxt.config 

// these boolean switches turn off the build for all but the store
const resetConfig = {
  loading: false,
  loadingIndicator: false,
  fetch: {
    client: false,
    server: false
  },
  features: {
    store: true,
    layouts: false,
    meta: false,
    middleware: false,
    transitions: false,
    deprecations: false,
    validate: false,
    asyncData: false,
    fetch: false,
    clientOnline: false,
    clientPrefetch: false,
    clientUseUrl: false,
    componentAliases: false,
    componentClientOnly: false
  },
  build: {
    indicator: false,
    terser: false
  }
}

// We keep a reference to Nuxt so we can close
// the server at the end of the test
let nuxt = null

// Init Nuxt.js and start listening on localhost:5000 BEFORE running your tests. We are combining our config file with our resetConfig using Object.assign into an empty object {}
test.before('Init Nuxt.js', async (t) => {
  t.timeout(600000)
  const config = Object.assign({}, nuxtConfig, resetConfig, {
    srcDir: nuxtConfig.srcDir, // don't worry if its not in your nuxt.config file. it has a default
    ignore: ['**/components/**/*', '**/layouts/**/*', '**/pages/**/*']
  })
  nuxt = new Nuxt(config)
  await new Builder(nuxt).build()
  nuxt.listen(5000, 'localhost')
})

// Then run our tests using the nuxt we defined initially
test.serial('Route / exists and renders correct HTML', async (t) => {
  t.timeout(600000) // Sometimes nuxt's response is slow. We increase the timeont to give it time to render
  const context = {}
  const { html } = await nuxt.renderRoute('/', context)
  t.true(html.includes('preload'))
  // t.true(true)
})

test.serial('Route / exits and renders title', async (t) => {
  t.timeout(600000)
  const { html } = await nuxt.renderRoute('/', {})
  const { JSDOM } = jsdom // this was the only way i could get JSDOM to work. normal import threw a functione error
  const { document } = (new JSDOM(html)).window
  t.true(document.title !== null && document.title !== undefined) // simple test to check if site has a title
})

这样做应该会奏效。但是,您可能仍然会遇到一些错误

  • ✖ 运行测试时超时。如果你得到这个,你就很不走运了。我认为问题出在 Ava 上,因为它没有给出描述性错误(并且删除任何 Nuxt 方法似乎都可以修复它),但到目前为止,即使使用上面的代码片段,有时它也能工作,有时却不能。
  • 此时我最好的猜测是 Nuxt 方面使用 renderRouterrenderAndGetWindow 有延迟,ava 不会等待,但几乎立即尝试任何这些方法 ava ”超时”,尽管为每个测试明确设置了 t.timeout。到目前为止,我的研究使我检查了 renderAndGetWindow 的超时(如果存在,但文档并未指明)。

这就是我所拥有的。