0

I'm attempting to focus on TDD with Typescript and so I built a new Vue project with the vue-cli (I selected to use Vue3, Typescript, and Jest). However when I ran the unit test out of the box it failed. After some investigation I found that the mount command from @vue/test-utils doesn't render any of the prop values:

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    {{ test }}
  </div>
</template>

<script lang="ts">
import { Options, Vue } from "vue-class-component";

@Options({
  props: {
    msg: String,
  }
})
export default class HelloWorld extends Vue {
  msg!: string;
  test: string = "It's a test";
}
</script>

example.specs.ts

import { mount } from "@vue/test-utils";
import HelloWorld from "@/components/HelloWorld.vue";

describe("HelloWorld.vue", () => {
  it("renders props.msg when passed", async () => {
    const msg = "new message";
    const wrapper = mount(HelloWorld, {
      props: { msg }
    });
    
    expect(wrapper.text()).toContain(msg);
  });
});

When I print wrapper.html() I get the following:

<div class="hello" msg="new message"><h1></h1></div>

It doesn't seem to be rendering msg or test at all into the html. It has it listed as a prop, but that's about it.

I think one of the causes might be that I'm using a Typescript component instead of a traditional which might throw it off, but I'm not sure.

Any advice/tips?

3 Answers 3

1

This problem was tracked to vue-jest. Just made a fix. https://github.com/vuejs/vue-jest/pull/299

Sign up to request clarification or add additional context in comments.

Comments

0
  1. Your HelloWorld component is not detected as a component, this is how you need to define it:

    @Component
    export default class HelloWorld extends Vue {
      @Prop() msg!: string;
    

@Component tells the compiler its a component.

@Prop() tells the compiler the msg property is a prop.

  1. Use propsData as mount options or use setProps documentation link:

    const wrapper = mount(HelloWorld, {
      propsData: {
        msg, // or msg: msg, 
      },
    });
    

Result:

  console.log tests/unit/example.spec.ts:13
    <div class="hello">
      <h1>
        new message
      </h1>
      It's a test
    </div>

1 Comment

Thank you for your response. I still haven't been able to get it to work though, but that's because I'm currently using Vue 3 so I've been jumping down that rabbit hole for the last little bit. If all else fails, I'll be sure to just switch back and work with Vue 2.
0

So this didn't exactly fix the problem, but it's an alternative method that I'm going to try: Instead of using class based components I went more for the functional based with the typescript implementation.

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    {{ test }}
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "HelloWorld",
  props: {
    msg: String
  },
  data() {
    return {
      test: "It's a test" as string
    }
  }
});
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.