Skip to content

setCompued does not work correctly for mapGetters #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eddyerburgh opened this issue Nov 15, 2017 · 9 comments
Closed

setCompued does not work correctly for mapGetters #176

eddyerburgh opened this issue Nov 15, 2017 · 9 comments
Labels

Comments

@eddyerburgh
Copy link
Member

computed: {
    ...mapGetters([
      'isTeamAdmin'
    ]),

    placeholder() {
      return this.isTeamAdmin ? 'Leader' : 'inboxMember'
    }
  }
test.only('placeholder computed is Leader if isTeamAdmin is true', () => {
    wrapper.setComputed({ isTeamAdmin: true });
    expect(wrapper.vm.placeholder).toContain('Leader');
  });
@lmiller1990
Copy link
Member

It has been working fine for me with stuff like

computed: {
  something () { return this.$store.getters['module/something']
}

and ...mapState also works fine. I might investigate this if you don't get a chance.

@eddyerburgh
Copy link
Member Author

eddyerburgh commented Nov 18, 2017

@lmiller1990 that would be great if you could investigate 😀

I copied this code over from another issue and haven't been able to test myself

@lmiller1990
Copy link
Member

Can confirm it does not work. Will look into tomorrow.

import { shallow } from 'vue-test-utils'
import mapGetters from './mapGetters'

test('it works', () => {
  const wrapper = shallow(mapGetters)

  wrapper.setComputed({ isTeamAdmin: true })
  expect(wrapper.vm.placeholder).toEqual('Leader')
})

TypeError: Cannot read property 'isTeamAdmin' of undefined

@lmiller1990
Copy link
Member

lmiller1990 commented Nov 20, 2017

The below is a minimum failing example that should pass using mapGetters.

<template>
  <div>
    {{ placeholder }}
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'
  export default {
    name: 'mapGetters',

    computed: {
      ...mapGetters([
        'isTeamAdmin'
      ]),

      placeholder () {
        return this.isTeamAdmin ? 'Leader' : 'inboxMember'
      }
    }
  }
</script>
import Vue from 'vue'
import Vuex from 'vuex'
import { shallow } from 'vue-test-utils'

import mapGetters from './mapGetters'

Vue.use(Vuex)

test('it works', () => {
  let store = new Vuex.Store({
    getters: {
      isTeamAdmin: () => true
    }
  })

  const wrapper = shallow(mapGetters, {
    store
  })

  wrapper.setComputed({ isTeamAdmin: false })

  expect(wrapper.vm.placeholder).toEqual('inboxMember') // fails. Still leader.
})

Edit: If you do return wrapper.setComputed({ isTeamAdmin: false }) it passes. Note I added return. Returning a promise makes Jest wait - that doesn't exactly explain why this works, setComputed doesn't return a promise does it? What's going on here? Hmm...

Edit: I think return in jest automatically wraps it in a promise.

Anyway, so I think the problem is related to the fact that mapGetters is not updated until $nextTick, which the promise returns adds allows the render to occur.

Was do you think we should do for this case @eddyerburgh ? Async test or even flush promises is a good workaround for now but this issue is cropping up a lot.

@wtho
Copy link
Contributor

wtho commented Nov 27, 2017

@lmiller1990 just trying to understand what you meant.

If you do return wrapper.setComputed({ isTeamAdmin: false }) it passes

Do you run the expect before the return? Otherwise it won't be executed at all, and no expectation / assertion means no possible fail.

I might just have misunderstood you though, please clarify.

Edit: Sorry for the confusion, I now understand there was an error thrown before that was somehow avoided with the return statement.

Interestingly enough the error is not avoidable in my setup with mocha using return, so it might actually be wrapped in a promise by jest.

@wtho
Copy link
Contributor

wtho commented Nov 27, 2017

I think I located the origin of the error in Vuex, this.$store being undefined here when querying the getter for its value.

This might a result of this.$options.store not being installed on the $options object, when the Vuex init hook gets executed on beforeCreate.

I do not understand enough about how vue-test-utils' vuex mocking works normally to go further right now.

@rayoplateado
Copy link

Hi all!
Any news on this? I'm facing the same problem.

Thank you, guys.

@lmiller1990
Copy link
Member

@rayoplateado can you make your test async and use something like flush promises? If you post the code you want to test I can help you in the right direction.

@eddyerburgh
Copy link
Member Author

This will be fixed in beta.9 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants