Javascript jest给出未知:无法读取属性';天气';未定义的don';我不知道什么是天气
我试图在vuex getter上实现一个测试,但它让我无法读取未定义的weather属性,我无法理解这里的“weather”是什么,我没有在任何地方声明任何天气变量,仍然不知道jest指的是什么天气。请帮我弄清楚。这是它给我带来的错误。如果需要,我可以提供更多的代码Javascript jest给出未知:无法读取属性';天气';未定义的don';我不知道什么是天气,javascript,vue.js,jestjs,vuex,vue-test-utils,Javascript,Vue.js,Jestjs,Vuex,Vue Test Utils,我试图在vuex getter上实现一个测试,但它让我无法读取未定义的weather属性,我无法理解这里的“weather”是什么,我没有在任何地方声明任何天气变量,仍然不知道jest指的是什么天气。请帮我弄清楚。这是它给我带来的错误。如果需要,我可以提供更多的代码 > weather-app@0.1.0 test C:\Users\guest1\Projects\Vue Cli\wheather-app > jest PASS src/test/navbar_test/nav
> 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 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");
}
}
});
我的天气温度组件
<template>
<div class="weather-temp">
<h1 class="weather-degree">{{getTemperature}}°</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>
{{getTemperature}}°;
{{data.weather[0].main}
从“vuex”导入{mapGetters};
导出默认值{
道具:[“数据”],
计算:{
…映射器([“getTemperature”])
}
};
调用设定温度的主要部件
<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"])
}
};
从“/Weather/Weather”导入天气;
从“/SideMenu/SideMenu”导入侧菜单;
从“vuex”导入{mapActions,mapGetters};
导出默认值{
名称:“主要”,
组成部分:{
天气,
副菜单
},
数据(){
返回{
天气数据:{}
};
},
方法:{
…映射操作([“设置温度”])
},
创建(){
取回(
`https://api.openweathermap.org/data/2.5/weather?lat=${this.getCoords.coords.latitude}&lon=${this.getCoords.coords.longitude}&units=metric&APPID=${process.env.VUE\u APPID}`
)
。然后(响应=>{
返回response.json();
})
。然后(数据=>{
控制台日志(数据);
this.weatherData=数据;
该设定温度(数据主温度);
});
},
计算:{
…映射器([“getCoords”])
}
};
///////忽略下面这个////////
Lorem Ipsum只是印刷和排版行业的虚拟文本。自16世纪以来,Lorem Ipsum一直是行业标准的虚拟文本,当时一位不知名的印刷商拿起一个打印工具,将其拼凑成一本打印样本书。它不仅存活了五个世纪,而且还跨越到电子排版,基本上保持不变。它在20世纪60年代随着包含Lorem Ipsum段落的Letraset表单的发布而流行,最近随着Aldus PageMaker等桌面发布软件包括Lorem Ipsum的版本而流行。问题是,您试图访问的属性值完全
未定义,在这种情况下,道具数据。或者使用类似于v-if
的方法,仅在定义了数据且具有长度时呈现/访问该值:
<template>
<div class="weather-temp">
<h1 class="weather-degree">{{ getTemperature }}°</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>
显示组件和存储的代码。听起来您试图访问组件中的某个嵌套属性,但出现了错误,因为该属性未提供给组件或未加载到存储的初始状态。我已添加了我的存储和weatherTemp组件,以及正在设置温度值的位置。我脑子里想的东西可能会导致在fetch调用上设置getTemperature值,但它的默认值是0,因此vue test utils也在调用fetch,而weather属性是在调用fetch后我所做的响应。它应该只调用getterhere's the git repository,但是我已经删除了这个测试,但是它是samei,正如文档中所说的那样,所以当我运行测试时,道具数据不在那里,这就是错误所在。如果我正在测试的任何组件中有任何道具,我必须将其作为propData传递?一般来说,不需要将道具传递给已安装的测试组件,但在您实现时,这可能是因为您的组件在尝试访问嵌套属性之前不会尝试执行任何类型的null或长度检查。这不仅仅是一个测试问题,如果生产中的天气组件中未定义道具数据,则会出现相同的错误,因为您尝试访问的属性缺少条件呈现或回退/默认逻辑。我在weathertemp的父组件中添加了一个检查。仅当获取数据并在本地状态中添加响应时才渲染,并将其作为prop传递,但如果不需要,那么为什么会抛出错误让我重新表述,在您的情况下,不重构组件,您需要将propsData
传递到此浅装组件,因为其他道具数据
未定义。它与在浏览器开发人员控制台中执行undefined[0].weather[0].main
时没有什么不同,它将给出相同的准确错误。这基本上就是测试中发生的事情,因为数据是未定义的。在您的实际应用程序中,这可能不会发生,因为您正在向组件传递道具,您需要在测试中复制道具。
<template>
<div class="weather-temp">
<h1 class="weather-degree">{{ getTemperature }}°</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>
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());
});