Skip to content

向组件传递数据

Vue Test Utils提供了几种在组件上设置dataprops的方法,使您能够在不同的场景中全面测试组件的行为。

在本节中,我们将探讨dataprops注入options,以及VueWrapper.setProps()来动态更新组件接收到的props

密码组件

我们将通过构建<Password>组件来演示上述功能。该组件验证密码是否符合某些标准,例如长度和复杂性。我们将从以下内容开始,添加功能以及测试,以确保功能正常工作:

js
const Password = {
  template: `
    <div>
      <input v-model="password">
    </div>
  `,
  data() {
    return {
      password: "",
    };
  },
};
const Password = {
  template: `
    <div>
      <input v-model="password">
    </div>
  `,
  data() {
    return {
      password: "",
    };
  },
};

我们将添加的第一个要求是最小长度。

使用props设置最小长度

我们希望在所有的项目中复用这个组件,每个项目可能都有不同的需求。因此,我们将使minLength成为一个道具,并将其传递给<Password>

如果密码小于minLength,我们将显示一个error。我们可以通过创建一个错误计算属性,并使用v-if有条件地渲染它来实现这一点:

js
const Password = {
  template: `
    <div>
      <input v-model="password">
      <div v-if="error">{{ error }}</div>
    </div>
  `,
  props: {
    minLength: {
      type: Number,
    },
  },
  computed: {
    error() {
      if (this.password.length < this.minLength) {
        return `Password must be at least ${this.minLength} characters.`;
      }
      return;
    },
  },
};
const Password = {
  template: `
    <div>
      <input v-model="password">
      <div v-if="error">{{ error }}</div>
    </div>
  `,
  props: {
    minLength: {
      type: Number,
    },
  },
  computed: {
    error() {
      if (this.password.length < this.minLength) {
        return `Password must be at least ${this.minLength} characters.`;
      }
      return;
    },
  },
};

为了测试这一点,我们需要设置minLength,以及一个小于该数字的password。我们可以使用dataprops注入options来实现这一点。最后,我们将断言呈现了正确的错误消息:

js
test("renders an error if length is too short", () => {
  const wrapper = mount(Password, {
    props: {
      minLength: 10,
    },
    data() {
      return {
        password: "short",
      };
    },
  });

  expect(wrapper.html()).toContain("Password must be at least 10 characters");
});
test("renders an error if length is too short", () => {
  const wrapper = mount(Password, {
    props: {
      minLength: 10,
    },
    data() {
      return {
        password: "short",
      };
    },
  });

  expect(wrapper.html()).toContain("Password must be at least 10 characters");
});

maxLength规则编写测试留给读者练习!另一种编写方法是使用setValue用太短的密码更新输入。您可以在Forms中了解更多信息。

使用 setProps

有时你可能需要写一个测试道具变化的副作用。如果props中的showtrue,这个简单的<Show>组件将呈现一个问候语。

vue
<template>
  <div v-if="show">{{ greeting }}</div>
</template>

<script>
export default {
  props: {
    show: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      greeting: "Hello",
    };
  },
};
</script>
<template>
  <div v-if="show">{{ greeting }}</div>
</template>

<script>
export default {
  props: {
    show: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      greeting: "Hello",
    };
  },
};
</script>

为了全面测试这一点,我们可能需要验证是否默认呈现了greeting。我们可以使用setProps()更新show参数,这会导致隐藏greeting

js
import { mount } from "@vue/test-utils";
import Show from "./Show.vue";

test("renders a greeting when show is true", async () => {
  const wrapper = mount(Show);
  expect(wrapper.html()).toContain("Hello");

  await wrapper.setProps({ show: false });

  expect(wrapper.html()).not.toContain("Hello");
});
import { mount } from "@vue/test-utils";
import Show from "./Show.vue";

test("renders a greeting when show is true", async () => {
  const wrapper = mount(Show);
  expect(wrapper.html()).toContain("Hello");

  await wrapper.setProps({ show: false });

  expect(wrapper.html()).not.toContain("Hello");
});

在调用setProps()时,我们还使用了await关键字,以确保在断言运行之前已经更新了DOM

结论

  • 使用propsdata挂载选项来预设组件的状态。
  • 在测试期间使用setProps()更新道具。
  • setProps()之前使用 await 关键字,以确保Vue将在测试继续之前更新DOM
  • 直接与组件交互可以为您提供更大的覆盖范围。考虑将setValue或触发器与数据结合使用,以确保一切正常工作。