开玩笑给出一个未知:无法读取未定义的 属性 'weather' 不知道什么是天气

jest giving an UNKNOWN : Cannot read property 'weather' of undefined don't know what is weather

我正在尝试对 vuex getter 进行测试,但它让我无法读取 属性 未定义的天气,我无法理解这里的“天气”是什么,我还没有声明这里任何地方的任何天气变量仍然不知道什么笑话是指天气。请帮我弄清楚。这是它抛出的错误 me.i 如果需要可以提供更多代码

> weather-app@0.1.0 test C:\Users\guest1\Projects\Vue Cli\wheather-app
> jest

 PASS  src/test/navbar_test/navbar.test.js (27.728s)
 PASS  src/test/app_test/App.test.js (34.842s)
 FAIL  src/test/weather_test/weatherTemp.test.js (35.418s)
  ● Console

    console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
      [Vue warn]: Error in render: "TypeError: Cannot read property 'weather' of undefined"

      found in

      ---> <Anonymous>
             <Root>
    console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884
      TypeError: Cannot read property 'weather' of undefined
          at Proxy.render (C:\Users\guest1\Projects\Vue Cli\wheather-app\src\components\weather\weatherTemp.vue:29:357)
          at VueComponent.Vue._render (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:3532:22)
          at VueComponent.updateComponent (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4048:21)
          at Watcher.get (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4459:25)
          at new Watcher (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4448:12)
          at mountComponent (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4055:3)
          at VueComponent.Object.<anonymous>.Vue.$mount (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:8386:10)
          at init (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:3112:13)
          at createComponent (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:5952:9)
          at createElm (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:5899:9)
          at VueComponent.patch [as __patch__] (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:6449:7)
          at VueComponent.Vue._update (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:3927:19)
          at VueComponent.updateComponent (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4048:10)
          at Watcher.get (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4459:25)
          at new Watcher (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4448:12)
          at mountComponent (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:4055:3)
          at VueComponent.Object.<anonymous>.Vue.$mount (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\vue\dist\vue.runtime.common.dev.js:8386:10)
          at mount (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\@vue\test-utils\dist\vue-test-utils.js:8649:21)
          at shallowMount (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\@vue\test-utils\dist\vue-test-utils.js:8677:10)
          at Object.it (C:\Users\guest1\Projects\Vue Cli\wheather-app\src\test\weather_test\weatherTemp.test.js:24:21)
          at Object.asyncJestTest (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:102:37)
          at resolve (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\jest-jasmine2\build\queueRunner.js:43:12)
          at new Promise (<anonymous>)
          at mapper (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\jest-jasmine2\build\queueRunner.js:26:19)
          at promise.then (C:\Users\guest1\Projects\Vue Cli\wheather-app\node_modules\jest-jasmine2\build\queueRunner.js:73:41)
          at process._tickCallback (internal/process/next_tick.js:68:7)

  ● Getters.vue › Renders "store.getters.clicks" in h1

    TypeError: Cannot read property 'weather' of undefined

      27 |   align-items: flex-end;
      28 |   width: 100%;
    > 29 |   height: auto;
         |                                    ^
      30 | }
      31 |
      32 | .weather-quote {

      at Proxy.render (src/components/weather/weatherTemp.vue:29:357)
      at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.dev.js:3532:22)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4048:21)
      at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)
      at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)
      at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)
      at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
      at init (node_modules/vue/dist/vue.runtime.common.dev.js:3112:13)
      at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5952:9)
      at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5899:9)
      at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6449:7)
      at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3927:19)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4048:10)
      at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)
      at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)
      at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)
      at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
      at mount (node_modules/@vue/test-utils/dist/vue-test-utils.js:8649:21)
      at shallowMount (node_modules/@vue/test-utils/dist/vue-test-utils.js:8677:10)
      at Object.it (src/test/weather_test/weatherTemp.test.js:24:21)

Test Suites: 1 failed, 2 passed, 3 total
Tests:       1 failed, 4 passed, 5 total
Snapshots:   0 total
Time:        63.368s
Ran all test suites.
npm ERR! Test failed.  See above for more details.

这是我的测试文件

import { shallowMount, createLocalVue } from "@vue/test-utils";
import Vuex from "vuex";
import weatherTemperature from "@/components/weather/weatherTemp.vue";

window.alert = jest.fn();
const localVue = createLocalVue();
localVue.use(Vuex);

describe("Getters.vue", () => {
  let getters;
  let store;

  beforeEach(() => {
    getters = {
      getTemperature: () => 2
    };

    store = new Vuex.Store({
      getters
    });
  });

  it('Renders "store.getters.clicks" in h1', () => {
    const wrapper = shallowMount(weatherTemperature, { store, localVue });
    const temp = wrapper.findAll(".weather-degree");
    expect(temp.text()).toBe(getters.getTemperature().toString());
  });
});

我的店铺

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
  state: {
    coords: {},
    burgerClicked: false,
    temperature: 0,
    locationAllowed: false
  },
  getters: {
    getCoords(state) {
      return state.coords;
    },
    getBurgerClicked(state) {
      return state.burgerClicked;
    },
    getTemperature(state) {
      return state.temperature;
    }
  },
  mutations: {
    setCoords(state, value) {
      state.coords = value;
    },
    setBurgerClick(state, value) {
      state.burgerClicked = value;
    },
    setTemperature(state, value) {
      state.temperature = value.toFixed(0);
    },

    convertToCelsius(state) {
      var tempInCelsius = ((state.temperature - 32) * 5) / 9;
      state.temperature = tempInCelsius.toFixed(0);
    },
    convertToFarenheit(state) {
      var tempInFarenheit = state.temperature * (9 / 5) + 32;
      state.temperature = tempInFarenheit.toFixed(0);
    }
  },
  actions: {
    setCoords(context, value) {
      context.commit("setCoords", value);
    },
    setBurgerClick(context, value) {
      context.commit("setBurgerClick", value);
    },
    setTemperature(context, value) {
      context.commit("setTemperature", value);
    },
    convertToFarenheit(context) {
      context.commit("convertToFarenheit");
    },
    convertToCelsius(context) {
      context.commit("convertToCelsius");
    }
  }
});

我的 Weathertemp 组件

   <template>
      <div class="weather-temp">
        <h1 class="weather-degree">{{getTemperature}}&#176;</h1>
        <div class="weather-quote">
          <h1 class="weather-quote-1">
            <b>{{data.weather[0].main}}</b>
          </h1>
        </div>
      </div>
    </template>
    <script>
    import { mapGetters } from "vuex";
    export default {
      props: ["data"],
      computed: {
        ...mapGetters(["getTemperature"])
      }
    };
    </script>
    

调用 setTemperature 的主要组件

<template>
  <div class="main" v-if="weatherData.main">
    <Weather :data="weatherData" />
    <SideMenu :data="weatherData"/>
  </div>
</template>

<script>
import Weather from "./weather/weather";
import SideMenu from "./sidemenu/sideMenu";
import {mapActions, mapGetters } from "vuex";
export default {
  name: "Main",
  components: {
    Weather,
    SideMenu
  },
  data() {
    return {
      weatherData: {}
    };
  },
  methods: {
    ...mapActions(["setTemperature"])
  },
  created() {
    fetch(
      `https://api.openweathermap.org/data/2.5/weather?lat=${this.getCoords.coords.latitude}&lon=${this.getCoords.coords.longitude}&units=metric&APPID=${process.env.VUE_APP_APPID}`
    )
      .then(response => {
        return response.json();
      })
      .then(data => {
        console.log(data);
        
        this.weatherData = data;
        this.setTemperature(data.main.temp);
      });
  },
  computed: {
    ...mapGetters(["getCoords"])
  }
};

问题是您正在尝试访问 属性 的完全 undefined 值,在本例中为道具 data。当数据已定义且长度为

时,使用 v-if 之类的东西仅 render/access 该值
<template>
  <div class="weather-temp">
    <h1 class="weather-degree">{{ getTemperature }}&#176;</h1>
    <div class="weather-quote">
      <h1 class="weather-quote-1">
        <b v-if="data && data.length">{{ data.weather[0].main }}</b>
      </h1>
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
  props: ["data"],
  computed: {
    ...mapGetters(["getTemperature"])
  }
};
</script>

无论如何我都会推荐这种方法,因为您可能会遇到 data 尚未完全解决的情况,并且您可能会在生产中遇到同样的错误,除非您只渲染 Weathertemp 有条件地在父级中。否则,您需要使用 propsData 将 prop data 传递给测试:

it('Renders "store.getters.clicks" in h1', () => {
  const propsData = { data: [{ weather: { main: 42 } }] };
  const wrapper = shallowMount(weatherTemperature, { store, localVue, propsData });
  const temp = wrapper.findAll(".weather-degree");
  expect(temp.text()).toBe(getters.getTemperature().toString());
});