soal / vue-mapbox

Vuejs 2 components for interacting with mapbox-gl-js
https://soal.github.io/vue-mapbox
MIT License
475 stars 146 forks source link

How to unit test vue-mapbox #208

Open stivenramireza opened 4 years ago

stivenramireza commented 4 years ago

Recently I have problems with my unit tests when I need to test an own component which uses a Vue MapBox component like MglMarker.

That's the component I trying test:

<template>
  <div>
    <div v-if="experimentName === 'price-marker'">
      <div v-if="variant === 'icon'">
        <MglMarker
          v-for="(item, index) of properties"
          :key="index"
          :coordinates="[item.property.longitude, item.property.latitude]"
        >
          <img
            v-if="propertyHover === index"
            slot="marker"
            class="icon-marker-selected"
            src="@/assets/img/markers/selected.png"
            @click="selectMarker(item)"
            @mouseleave="setPropertyHover(-1)"
          />
          <img
            v-if="propertyHover !== index"
            slot="marker"
            class="icon-marker"
            src="@/assets/img/markers/no-selected.png"
            @click="selectMarker(item)"
            @mouseenter="setPropertyHover(index)"
          />
        </MglMarker>
      </div>
      <div v-if="variant === 'price'">
        <MglMarker
          v-for="(item, index) of properties"
          :key="index"
          :coordinates="[item.property.longitude, item.property.latitude]"
        >
          <div
            v-if="propertyHover === index"
            slot="marker"
            class="price-marker-selected"
            @click="selectMarker(item)"
            @mouseleave="setPropertyHover(-1)"
          >
            <h5 class="price-text">{{ item.sellValue | toPesos }}</h5>
          </div>
          <div
            v-if="propertyHover !== index"
            slot="marker"
            class="price-marker"
            @click="selectMarker(item)"
            @mouseenter="setPropertyHover(index)"
          >
            <h5 class="price-text">{{ item.sellValue | toPesos }}</h5>
          </div>
        </MglMarker>
      </div>
    </div>
  </div>
</template>

<script>
import { MglMarker } from 'vue-mapbox'
import { mapMutations, mapState } from 'vuex'
export default {
  filters: {
    toPesos: value => {
      return value !== 'Precio'
        ? `$${('' + value).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`
        : value
    }
  },
  components: {
    MglMarker
  },
  props: {
    properties: {
      type: Array,
      default: () => {
        return []
      }
    },
    generateDetailUrl: {
      type: Function,
      default: () => {
        return ''
      }
    }
  },
  data() {
    return {
      experimentName: this.$exp.name,
      variant: this.$exp.$activeVariants[0]
    }
  },
  computed: {
    ...mapState({
      propertyHover: state => state.search.propertyHover
    })
  },
  methods: {
    ...mapMutations({
      setPropertyHover: 'search/setPropertyHover'
    }),
    selectMarker(item) {
      this.$router.push(this.generateDetailUrl(item))
    }
  }
}
</script>

That's the failed test:

import Vuex from 'vuex'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import MapMarker from '@/components/map/MapMarker.vue'
import MglMarker from 'vue-mapbox'

const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(MglMarker)

describe('MapMarker.vue', () => {
    let state
    let store

    const $exp = {
        name: 'price-marker',
        $activeVariants: ['icon']
    }

    const mapMarkerProps = {
        properties: [
            {
                id: 1,
                rentValue: 1800000,
                status: 'PROMOTION',
                type: 'APARTMENT'
            },
            {
                id: 2,
                rentValue: 420000,
                status: 'PROMOTION',
                type: 'APARTMENT'
            }
        ],
        generateDetailUrl: () => {
            return '/apartment-to-rent/neighborhood-city/10000'
        }
    }

    const mapMarkerData = {
        experimentName: 'price-marker',
        variant: 'icon'
    }

    beforeEach(() => {
        state = {
            propertyHover: -1
        }

        store = new Vuex.Store({
            modules: {
              search: {
                state
              }
            }
        })
    })

    it('render correct MglMarker component', () => {
        const wrapper = shallowMount(MapMarker, {
            localVue,
            store,
            mocks: {
                $exp
            }
        })
        wrapper.setProps(mapMarkerProps)
        wrapper.setData(mapMarkerData)
        expect(wrapper.findComponent(MglMarker).exists()).toBe(true)
    })

})

How can I fix it?

Thanks in advance!

blueivywave commented 4 years ago

What is the problem exactly?

stivenramireza commented 4 years ago

What is the problem exactly?

Definitely I think the problem is with the component Vue-Mapbox, because I don't know how to mock it successfully. When I debug my test I see that this component doesn't render and for that reason I cannot access to innermost divs and imgs.