-
Notifications
You must be signed in to change notification settings - Fork 112
Unable to use direct-vuex
#146
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
@kosciak9 const { store } = createDirectStore({
// … store implementation here …
});
render(Comp, {}, localVue => {
localVue.use(Vuex);
return {
store
};
}); |
Hey, you are right, it works quite well. I was trying to fight it for quite a long time and seems like I missed the most obvious answer. :) Short code example for anyone with same issue (TypeScript, but didn't actually test it): it("directVuex example", async () => {
// you have to .use(Vuex) before createDirectStore
const localVue = createLocalVue();
localVue.use(Vuex);
const increment = jest.fn();
const decrement = jest.fn();
const { store } = createDirectStore({
state: () => {
return { counter: 0 };
},
getters: {
counter: state => state.counter,
},
mutations: {
increment,
decrement
},
});
const { getByLabelText } = render(
ExampleComponent,
{
localVue,
},
() => ({
store: store.original,
})
);
await userEvent.click(getByLabelText("Add one"));
expect(increment).toHaveBeenCalled();
await userEvent.click(getByLabelText("Remove one"));
expect(decrement).not.toHaveBeenCalled();
}); |
Yeah, but you would have to use it like this: const increment = jest.fn();
const decrement = jest.fn();
const { getByLabelText } = render(
ExampleComponent,
{
localVue,
},
(localVue) => {
localVue.use(Vuex);
const { store } = createDirectStore({
state: () => {
return { counter: 0 };
},
getters: {
counter: (state) => state.counter,
},
mutations: {
increment,
decrement,
},
});
return { store: store.original };
}
); As |
Isn't the following an option? I've never used const increment = jest.fn();
const decrement = jest.fn();
const { getByLabelText } = render(
ExampleComponent,
{}, // <-- without importing and passing localVue
(vue) => {
vue.use(Vuex);
const { store } = createDirectStore({
state: () => {
return { counter: 0 };
},
getters: {
counter: (state) => state.counter,
},
mutations: {
increment,
decrement,
},
});
return { store: store.original };
}
); |
Seems like we have same idea :D I accidentally didn't remove localVue from options but otherwise code is the same. What about my concerns? Looking at what's |
Besides that, I’d actually advice against doing tests like this. Here, you hardcouple your implementation with the output. What if you rename your action at some point to incrementBy? The important unit here is the Dom output and the caused side effects, like requests. Handling of Vuex happens totally inside the component. Also, I’m not suggesting not to test your store at all - I think it deserves to be tested - just not within the component. The value lies in the output and expects on them in the Dom and not an the Vuex actions called. |
While I understand your point of view and also dislike this way of testing, sometimes you have to draw a line between units that you're testing, even if those units are quite huge. In our case we abstracted any communication with APIs to Vuex, and provide just one or two actions that will check input and refetch accordingly. UI components are decoupled from anything besides looking at fetchState and actual data. That's why mocked stores are mostly just one getter and one action. It's a more complicated props setup, that allows us to do I'm not sure if that's the greatest approach but it allows us to think in smaller blocks (UI, Server) and separate logic. We do have tests that use our "real" store the way user is using them, but such a big test failing won't give you quick insight into what have you actually broke. It's like they say in Python's Zen: I feel practicality here beats purity of DOM testing. :) |
Describe the bug Because of the way store is initialized, I'm unable to use
direct-vuex
stores. Short summary,direct-vuex
is a "wrapper" forvuex
to provide typing for store. Thanks to it you can dothis.$store.dispatch.myAction(myPayload)
happily.To Reproduce Steps to reproduce the behavior:
store
viacreateDirectStore
fromdirect-vuex
.Vuex.Store
so initialization inrender
fails (getters should be function)Expected behavior
I can use
direct-vuex
stores.I'm skipping few sections as I already know the solution (or at least where problem originates):
Problematic code here.
I do realize why it's written this way.
Question to the maintainers is, how do you want to implement it. Or whenever you want to implement it at all! There could be boolean switch in additionalOptions to skip store initialization (like
initializeStore
, by default set to true, to not break API), or some other options likedirectVuexStore
which you can use to add to theVue
instance instead of plainstore
. I'm happy to help with this in any way you need.The text was updated successfully, but these errors were encountered: