I'm trying to find a way to proper test this, I've been reading the docs and a lot of people seems to have a similar issue.
function emitterFn (instance) {
return eventChannel(emit => {
const listener = instance.changes()
.on('change', info => {
emit(info)
})
return () => listener.cancel()
})
}
function* something () {
const emitter = yield call(emitterFn)
try {
while (true) {
let payload = yield take(emitter)
/* code omitted */
}
}
}
What is the proper way to get the pattern/channel for that emitter?
let output = saga.next({}).value
let expected = take({})
I doesn't read the proper channel, I've also tried to instanciate the channel and pass it as an argument and it didn't work
let channel = myChannelFunction()
let output = saga.next(channel).value
let expected = take(channel)
Any ideas?
this should pretty much work
const saga = something()
let actual = saga.next()
let expected = call(emitterFn)
const chan = channel()
actual = saga.next(chan).value
expected = take(chan)
@Andarist Almost, It still throws the take channelOrPattern is not valid, I checked a little and notice the emitter is undefined when running the tests, however, it works fine one the code:
function* something () {
const emitter = yield call(emitterFn)
try {
while (true) {
let payload = yield take(emitter) // <--- this is undefined
/* code omitted */
}
}
}
That is causing the error when testing I guess, so I tried adding the emitter to the previous next() to make it available, but I guess the same result.
If it helps, my event channel is the same as #631
You're trying to test the emitterFn function in your example, correct? If that is the case, you should do that outside of a saga. You'll need to fake the instance that you pass into emitterFn, something like this FakeEmitter class that allows you to control when events are emitted and the emit function from the eventChannel is called. Looks like you're mock instance might be slightly more involved with properly mocking the behavior of the changes method, but pretty similar.
When you go to test the channel's closing behavior, create a spy on the cancel method of the instance you passed it, and assert that its called. i.e.
const cancel = jest.spyOn(emitter, 'cancel')
channel.close()
expect(cancel).toHaveBeenCalledWith(/*whatever arguments it should have been called with*/)
When you go to write a test for a saga that uses the channel creator function, you don't need to mess with channels, you just call next on the iterator with whatever you need. When you need to pass in a fake channel, you can do it with a couple of simple no-op functions.
Here's an example from one of my project's tests (using redux-saga-test-plan , which I heartily recommend)
Most helpful comment
this should pretty much work