Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 手动将值传递给生成器会产生jest测试的意外结果_Javascript_Reactjs_Generator_Jestjs - Fatal编程技术网

Javascript 手动将值传递给生成器会产生jest测试的意外结果

Javascript 手动将值传递给生成器会产生jest测试的意外结果,javascript,reactjs,generator,jestjs,Javascript,Reactjs,Generator,Jestjs,我有以下redux传奇,它进行api调用并处理结果: import { takeLatest } from 'redux-saga' import { call, put } from 'redux-saga/effects' import { normalize, arrayOf } from 'normalizr' import * as actions from './actions' import * as schemas from './schemas' import * as typ

我有以下redux传奇,它进行api调用并处理结果:

import { takeLatest } from 'redux-saga'
import { call, put } from 'redux-saga/effects'
import { normalize, arrayOf } from 'normalizr'
import * as actions from './actions'
import * as schemas from './schemas'
import * as types from './actionTypes'
import { api, constants as apiConstants } from '../../services/api'

export function* fetchWorks() {
  const { response, error } = yield call(api.getJson, apiConstants.WORKS_ENDPOINT)
  if (response) {
    const normalized = normalize(response.items, arrayOf(schemas.works))
    yield put(actions.fetchWorksSuccess(normalized))
  } else {
    yield put(actions.fetchWorksFail(error))
  }
}
我正在测试这些玩笑测试是否一切正常:

import { takeLatest } from 'redux-saga'
import { call, put } from 'redux-saga/effects'
import * as sagas from './sagas'
import * as actions from './actions'
import * as types from './actionTypes'
import { api, constants as apiConstants } from '../../services/api'

describe('works saga', () => {
  describe('fetchWorks', () => {
    it('should fetch data', () => {
      const generator = sagas.fetchWorks()
      const actual = generator.next().value
      const expected = call(api.getJson, apiConstants.WORKS_ENDPOINT)
      expect(actual).toEqual(expected)
    })

    // this test requires me to pass a response object to the generator
    it('should put fetchWorksSuccess on a response', () => {
      // so I create it here
      const response = {
        items: [{
          sys: { id: '1' },
          fields: { content: 'content' }
        }]
      }
      const generator = sagas.fetchWorks()
      const expected = put(actions.fetchWorksSuccess())
      // but I would expect to pass it here    
      generator.next()
      // but actually the test only succeeds if I pass it here
      const actual = generator.next({ response }).value
      expect(actual).toEqual(expected)
    })

    // same goes for this test
    it('should put fetchWorksFail on errors', () => {
      const error = new Error('Something went wrong')
      const generator = sagas.fetchWorks()
      const expected = put(actions.fetchWorksFail())
      generator.next()
      const actual = generator.next({ error }).value
      expect(actual).toEqual(expected)
    })
  })
})
但是,对于
'should fetchWorksSuccess on response'
'should fetchWorksFail on errors'
测试,我必须手动将
{response}
{error}
对象分别传递到每个生成器中


我知道这些对象是必需的(因为if语句检查是否有响应),但我不明白为什么我必须将其传递给第二个
。next()
,而不是第一个?因为在我看来,第一个
yield
生成响应或错误对象,而不是第二个。有人知道为什么吗?

这不是反应,而是发电机

generator.next()
的第一次调用启动生成器,而不是从yield调用返回:

>>> function *example_generator() {
  console.log('before first yield', Array.slice(arguments));
  var first_yield = yield 'first';
  console.log('first yield returned', first_yield);
  var second_yield = yield 'second';
  console.log('second yield returned', second_yield);
  return 'done';
}
>>> generator = example_generator("generator", "creation")
Generator {}
>>> generator.next("first next")
before first yield  Array [ "generator", "creation" ]
Object { value: "first", done: false }
>>> generator.next("second next")
first yield returned second next
Object { value: "second", done: false }
>>> generator.next("third next")
second yield returned third next
Object { value: "done", done: true }
fetchWorks()
的初始调用会创建生成器对象,但实际上不会启动生成器


这样考虑-对
next()
的第一次调用将为您提供传递给第一次
的值yield
;第二次调用
next()
时给出的参数允许您指定第一次
yield
的返回值。MDN文档并没有真正帮助我理解这一点。您的回答,结合本文()和对codepen()的实验,帮助我理解了它。谢谢