1
votes

I'm developing some tests for single file components in VueJs. These components use font-awesome.

This is my App, as you can see I have fontawesome available for all child components.

import { createApp } from 'vue';
import App from './App.vue';
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { fas } from "@fortawesome/free-solid-svg-icons";
import { library } from '@fortawesome/fontawesome-svg-core';

library.add(fas);

createApp(App)
.component("font-awesome-icon", FontAwesomeIcon)
.mount('#app');

Here's a test

import { mount } from '@vue/test-utils'
import ListComponent from '@/components/ListComponent.vue'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';

let someData = [{
  name: 'Some person name', 
  key: '2222222',
  moreInfo: [
    {title: 'aa'},
    {title: 'bb'},
  ]
},
{
  name: 'Some other person name', 
  key: '12321123,
  moreInfo: [
    {title: 'cc'},
    {title: 'x'},
  ]
},
}];

let wrapper = mount(ListComponent, {
  propsData: {
    someData
  },
  stubs: {
    'font-awesome-icon': FontAwesomeIcon
  }
});

describe('ListadoImputados.vue', () => {.... tests ....});

Test details are not important, I don't know how to add / include font-awesome-icon in the context so i can avoid getting the following warnings

console.warn node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:40
    [Vue warn]: Failed to resolve component: font-awesome-icon

I tried adding this dependency as a mock and stub but no luck. Also importing Fontawesome at the top of the file does not work, the warning is still showing. I was thinking maybe in creating a vue app in the test file and inject the component like this

createApp(App)
.component("font-awesome-icon", FontAwesomeIcon)
.mount('#app');

but I'm copying and pasting code and I'm not sure this is the right way. Is there a way to add this dependencies to my test context? I'm using Vue 3, vue-test-utils + jest

1
If FontAwesomeIcon is not relevant for your tests, all you need is stubs: { FontAwesomeIcon: true }, without importing it. To automatically stub all subcomponents, you can specify shallow: true in mount's options. It's the equivalent of going through the entire list of sub-components and assigning true to them (that's what shallow: true does). - tao
The error you're seeing is not directly related to the test. It's related to the test environment not being able to resolve FontAwesomeIcon - it's likely a path error. Once you provide the correct path to it (or fix whatever it is that's failing the import), what you have should start working. - tao
i forgot to tell that I need the complete mounting, not shallow, because my tests are going deeper. I don't care testing fontawesome. I know what you mean, but my tests are failing if I used shallowMounting - Mauro Alvarez

1 Answers

1
votes

In Vue Test Utils v2 (for Vue 3), the stubs mounting option is moved into global.stubs. Also note that a stub does nothing by definition, so stubbing the component only requires providing the component name.

Your mounting options should look like this:

const wrapper = mount(ListComponent, {
  global: {
    stubs: ['FontAwesomeIcon']
  }
})

If for some reason you need the actual component, you could technically provide the component definition as a "stub", but you'd also need to initialize the icons for it as you would in the app's startup:

// assume only `faUserSecret` icon used in `ListComponent`
import { library } from '@fortawesome/fontawesome-svg-core'
import { faUserSecret } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(faUserSecret)

//...

const wrapper = mount(ListComponent, {
  global: {
    stubs: { FontAwesomeIcon }
  }
})