testing-library / vue-testing-library

🦎 Simple and complete Vue.js testing utilities that encourage good testing practices.
http://testing-library.com/vue
MIT License
1.09k stars 109 forks source link

Problem using `testing-library` with vue <script setup> #294

Closed TomBell95 closed 1 year ago

TomBell95 commented 1 year ago

Describe the bug When testing using <script setup>, the component is closed by default and we should have access to anything we expose through defineExpose? Is this a limitation of using testing-library compared to vue/test-utils where you can access anything exposed by the component?

Error: TypeError: Cannot destructure property 'expose' of 'undefined' as it is undefined.

To Reproduce App.vue

<script setup>
import { ref } from "vue";
const hello = ref("hello world");
const setLocale = () => {
  return "IE";
};
defineExpose({ setLocale, hello });
</script>

<template>
  <p>{{ hello }}</p>
</template>

App.test.js

import { describe, test } from "vitest";
import { render } from "@testing-library/vue";
import "@testing-library/jest-dom";
import App from "../App.vue";

describe("App.vue", () => {
  test("should display hello", async () => {
    render(App);
    console.log(App);
    console.log(App.setup()); // <- Error
    console.log(App.setup().hello); // <- Error
    console.log(App.setup().setLocale); // <- Error
  });
});

Expected behavior

We should be able to access functions or variables inside the component. As per the vue docs on defineExpose when using <script setup>. I understand that the philosophy behind testing-library is behaviour based testing, but there are edge cases where this is valid.

I would have assumed, just like vue/test-utils, we could still access anything exposed by the component? The equivalent is wrapper.vm.FOO (link here) - is this possible in testing-library?

Additional context

I raised this my specific use case on stackoverflow here: https://stackoverflow.com/q/75298194/15369125

afontcu commented 1 year ago

Hi! Thanks for the question.

We should be able to access functions or variables inside the component

I would have assumed, just like vue/test-utils, we could still access anything exposed by the component?

Actually no, this is not the philosophy of Testing Library.

If there's a specific use case that you can't test without accessing internals (from my own experience this is unlikely and usually related to specific stuff that plugs into Vue internals), I'd recommend writing that test using @vue/test-utils (Vue Testing Library uses it under the hood, so the dependency is already there. You can simply import it).