Skip to content
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

How to write test #141

Open
hern12 opened this issue Mar 22, 2020 · 6 comments
Open

How to write test #141

hern12 opened this issue Mar 22, 2020 · 6 comments

Comments

@hern12
Copy link

hern12 commented Mar 22, 2020

Hello I love this library and I want to test it but I do not know how to start writing test with jest please show some example

@solkimicreb
Copy link
Member

That's a good question. There is not much difference between testing components with vanilla React state and easy-state. I recommend you to use react-testing-library. The docs should be pretty clear there.

React component testing is a pain in general and hooks just made it worse in my opinion. We will ship a tiny new feature with the next release (next week) that should make pure logic testing easier without the pain of React component testing.

@solkimicreb
Copy link
Member

The new feature that I mentioned only made it into the experimental release (It needs more internal testing). I will keep this issue open until we add it to a stable release and write testing guidelines to the docs.

Side note: did you try react-testing-library?

@lostincomputer
Copy link

lostincomputer commented Apr 23, 2020

I think it would be great if there is a guidance on how to create a new store per test.

it("...", () => {
   // create a store instance
}

it("...", () => {
   // create another store instance
}

The current examples don't show how to do that. The examples just export a single instance per global store.

@solkimicreb
Copy link
Member

solkimicreb commented Apr 24, 2020

@lostincomputer You can create store factories for that.

export function appStoreFactory () {
  const appStore = store({
    // ...
  })
  return appStore;
}

// export a single default global store, or use `appStoreFactory` to create new instances for local state or tests
export default appStore()

Same applies for local state:

Do this:

// you can export and test this instead of testing your whole components
function localStoreFactory () {
  return store({})
}

export default view(() => {
  const localStore = localStoreFactory()
  return <div />
})

Instead of this:

export default view(() => {
  // store is encapsulated, you can only test it through the component
  const localStore = store({})
  return <div />
})

I hope this helps.

@lostincomputer
Copy link

lostincomputer commented May 8, 2020

@solkimicreb Yes, that is what I do. Thanks for your answer.

My question is more on how to test React components that use a shared global store.

// First component
export default view(() => (<div>{globalStore.property</div>))

// Second component
export default view(() => (<h1>{globalStore.property</h1>))

Previously, I mocked module that exports the global store but I found the mocking code to be ugly (for example, I have to reset the mock for each test) so I switched to providing the global store via React Provider similar to how Redux and MobX exposes their store.

I'm just wondering if React Easy State has a recommended way.

@solkimicreb
Copy link
Member

solkimicreb commented May 8, 2020

That's a good question. Honestly, I don't test my views but that's a personal preference. I would either do what you do at the moment with a provider and context or I would embrace the container/presentational component pattern.

Container comp, should not be tested

import store1 from './store1'
import store2 from './store2'

export default function CounterContainer () {
  return <Counter num1={store1.num} num2={store2.num} inc1={store1.inc} ...etc />
}

Presentation Comp, to be tested

export default function Counter ({ num1, num2, inc1, ...etc}) {
  // ... your logic here
}

You can make a helper function - like Redux's connect - to reduce the boilerplate if you go this way.


  • Option 1 (Provider) produces cleaner code but slightly more complex tests (with all the Provider wrapping).
  • Option 2 (container/presentational) produces more verbose code but cleaner tests.

At the moment we do not plan to add any dependency injection to this library directly because React has decent support for it out of the box. Maybe we will create another lib in the future for devs who wish to use DI in their code.

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

No branches or pull requests

3 participants