Vue项目移动端集成测试时,怎么模拟手机横屏触发的事件?

纪娜 阅读 37

我在写一个移动端Vue组件的集成测试,里面用到了横屏检测功能:


<template>
  <div @orientationchange="handleOrientation">
    <p>当前方向:{{ orientation }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const orientation = ref('portrait')

const handleOrientation = () => {
  orientation.value = window.innerHeight > window.innerWidth ? 'portrait' : 'landscape'
}
</script>

测试时用Jest+Vue Test Utils写断言,发现直接修改window.orientation属性没效果,用window.matchMedia(‘(orientation: landscape)’)也没触发事件。有什么办法能在测试环境里模拟真实的横屏操作吗?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
IT人利伟
测试里模拟横屏事件不能直接改 window.orientation,这个属性在大部分浏览器里都是只读的,Jest环境更不会触发真实行为。你得手动 dispatch 事件,并且 mock innerWidthinnerHeight 的值。

核心思路是用 Object.defineProperty 劫持 window.innerHeightinnerWidth,然后手动触发 orientationchange 事件。Vue Test Utils 渲染完组件后,先改屏幕尺寸模拟横屏,再 dispatch 事件就行了。

比如你在测试用例里这么写:

import { mount } from '@vue/test-utils'
import YourComponent from './YourComponent.vue'

test('should detect landscape orientation', () => {
// 模拟横屏尺寸
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 800
})
Object.defineProperty(window, 'innerHeight', {
writable: true,
configurable: true,
value: 600
})

const wrapper = mount(YourComponent)

// 触发 orientationchange 事件
window.dispatchEvent(new Event('orientationchange'))

// 断言方向变为 landscape
expect(wrapper.find('p').text()).toContain('landscape')
})


注意 writable: true 要设上,不然没法重定义。另外别忘了某些逻辑可能依赖 screen.orientation.angle 或其他属性,如果组件里用了可以继续 defineProperty 补全。

CSS的话,这种响应式布局一般靠 media query 控制样式,但你的逻辑是 JS 判断宽高比,所以重点还是 mock 尺寸 + 手动触发事件。这套方法我测过 Vue 2 和 3 都行,放心用。
点赞 7
2026-02-12 16:09
❤琪航
❤琪航 Lv1
用jest模拟window.orientation和触发事件就行,直接改值加dispatchEvent

window.orientation = 90
window.dispatchEvent(new Event('orientationchange'))
点赞 4
2026-02-05 21:03