-
Notifications
You must be signed in to change notification settings - Fork 433
this.$t is not a function in a class component #505
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
Comments
@kaorun343 As you can see this is rather a bug in |
Does this work in a browser with the real |
@lmiller1990 |
I am guessing VCC does some transform first, then VTU applies the mock I would recommend using Are you interested in investigating this bug/making a PR? |
@lmiller1990 vue-class-component/src/data.ts Line 5 in 1643346
If you debug BTW. accessing |
Interesting. I suppose this makes sense. Class Component -> VCC transform -> VTU $mocks. By the time $mocks happens, it is too late and the component is using whatever I do not see any way we can fix this in VTU - whatever we do, it's going to be too late to get the mocked value in. Seems VTU v2 and the next version of class component exhibit the same bug for the same reason. An alternative would be using a |
When the mocking exactly happens in vue-test-utils? (you can show this in the source code) Does mocking occur after creating a component? If yes, then this is problematic for class components, because this Could you check the VCC source code to see if there is any solution to this? Maybe this can be fixed in VCC source code?
Could you show an example? |
The mocking happens here. I don't see a way to fix this by patching VCC.
Looks like my idea doesn't work. I thought I could do something like this: class MockPlugin {
static install(Vue: any) {
Vue.$t = (key: string) => key
}
}
const localVue = createLocalVue()
localVue.use(MockPlugin)
describe('App.vue', () => {
it('some unit test', () => {
const wrapper = mount(App, {
localVue
});
expect(wrapper).toBeDefined();
})
}) But the result is the same. Hm. I think something else is at work here... I cannot even get this to work with the real i18n plugin. |
Ok... this worked (webpack + mocha combo). import { expect } from 'chai'
import Vue from 'vue'
import { mount, createLocalVue } from '@vue/test-utils'
import App from '@/App.vue'
class i18n {
static install(Vue: any) {
Vue.prototype.$t = (key: string) => key
}
}
Vue.use(i18n)
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const wrapper = mount(App)
console.log(wrapper.html())
})
}) But this does not: import { expect } from 'chai'
import Vue from 'vue'
import { mount, createLocalVue } from '@vue/test-utils'
import App from '@/App.vue'
class i18n {
static install(Vue: any) {
Vue.prototype.$t = (key: string) => key
}
}
const localVue = createLocalVue()
localVue.use(i18n)
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const wrapper = mount(App, {
localVue
})
console.log(wrapper.html())
})
}) I guess when VCC does it's thing, If you dont't mind using a mutated global Vue for all your tests, you could do something like I've shown here (making a "fake" I am still not sure on how we can make |
A repro excluded the dep to vue-test-utils would be: @Component
class Base extends Vue {
test() {
return 'base'
}
}
@Component
class Test extends Base {
result = this.test()
}
const vm = new Test()
expect(vm.result).to.equal('base')
const Replaced = Vue.extend()
Replaced.prototype.test = () => 'replaced'
const replaced: Test = new (Replaced.extend({
...(Test as any).options,
}))()
expect(replaced.result).to.equal('replaced') We could replace the prototype of the original constructor with the one of |
I thought about this too, but doesn't feel like a great solution. We should also think about how this works in vue-class-component-next and vue-test-utils-next. vue-test-utils-next has the exact same problem... but does not use the |
hope it helps you. @Component
export default class App extends Vue {
private someData();
created() {
this.someData = this.$t("message");
}
}
|
@ktsn |
Subject of the issue
I have the following component
and the following unit test
When running this unit test, it fails with the following error:
Steps to reproduce
Just run unit tests in this project:
i18n-test.zip
Expected behaviour
Error
this.$t is not a function
should not occur. The$t
function is mocked.Actual behaviour
An error
this.$t is not a function
is thrown.Additional context
If I convert
someData
to computed property, like this:the error is gone.
The text was updated successfully, but these errors were encountered: