从获取请求返回的JSON在test和dev中有所不同

时间:2016-10-19 13:24:06

标签: reactjs redux karma-runner fetch enzyme

我希望我的问题标题足够容易理解。我真的不能想出一个更好的方式来表达它,并且字符数限制会破坏我的球。

我正在进行的项目中遇到的问题是使用React,Redux和react-router-redux和redux-auth-wrapper之类的软件包。

为了测试我正在使用带有Enzyme,Sinon和Chai的Karma测试运行器。在测试中,我使用fetchMock来模拟对我正在使用的API的任何请求。我使用Webpack捆绑所有内容。

我面临的问题是我编写的代码(修改后的this初学者模板非常严格),但我为他们编写的测试并没有产生正确的结果。当我调度一个从我们的身份验证API获取令牌的动作时,这个行为很奇怪。

我正在调度的Redux动作如下:

export function fetchToken(data) {
  return function(dispatch) {
    dispatch(requestTokenCreate(data))

    // Let's fetch this user a token, shall we?
    var headers = new Headers()
    headers.append("Content-Type", "application/json")
    headers.append("Accept", "application/json")

    let requestParams = {
      method: 'POST',
      headers: headers,
      mode: 'cors',
      cache: 'default',
      body: JSON.stringify({
        subdomain: data.subdomain,
        login: data.username,
        password: data.password
      })
    }
    data = {
      subdomain: data.subdomain,
      username: data.username
    }
    var serverUrl = (__DEV__ || __TEST__) ? "http://subdomain.easyposonline.dev:3000/api/v1" : "https://subdomain.easyposonline.nl/api/v1"
    serverUrl = serverUrl.replace("subdomain", data.subdomain)
    return fetch(serverUrl + "/auth_tokens/create", requestParams)
      .then(response => response.json())
      .then(json => {
        return dispatch(receiveTokenCreate(json, data))
      }
    )
  }
}

与我的问题相关的一点是:

return fetch(serverUrl + "/auth_tokens/create", requestParams)
  .then(response => response.json())
  .then(json => {
      return dispatch(receiveTokenCreate(json, data))
  }
)

当我在开发代码中发送此操作时,它运行正常!这将返回以下响应:

{success: true, token: "a3PC6y6nx1f63o2b13YWz7LYUHdidYui"}

但是,当从相关测试中调度操作时,我会收到以下响应:

{type: 'RECEIVE_USER_TOKEN_CREATE', json: Object{success: true, token: 'qicXyn6BhYhyoBuA_SFoZtTDN'}, payload: Object{subdomain: 'test-teun', username: 'teun@easypos.nl', token: 'qicXyn6BhYhyoBuA_SFoZtTDN'}}

因此,代码不会返回正确的响应,而是返回整个Redux操作。这导致我的测试失败,因为我最终在我正在测试的代码中进行了一些递归:

{type: 'RECEIVE_USER_TOKEN_CREATE', response: Object{type: 'RECEIVE_USER_TOKEN_CREATE', json: Object{success: ..., token: ...}, payload: Object{subdomain: ..., username: ..., token: ...}}, payload: Object{subdomain: 'test-teun', username: 'teun@easypos.nl'}}

我在这里不知所措。可能我忽略了一些非常简单的事情,但现在已经看了几个小时并开始失去我的恐惧!

我写的测试文件如下,也许我正在以错误的方式设置测试:

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
// import nock from 'nock'
import 'isomorphic-fetch'
import fetchMock from 'fetch-mock'

import SignInView from 'routes/SignIn'
import * as constants from 'constants'
import { fetchToken, destroyToken } from 'actions/user'
import _ from 'underscore'

describe('(Route) SignIn', () => {
  let _route = SignInView({})

  // Auth token request
  const authTokenCreateSuccessfulRequest = {
    subdomain: 'test-teun',
    username: 'teun@easypos.nl',
    password: 'psv4teun'
  }
  const authTokenCreateFailedRequest = {
    subdomain: 'test-teun',
    username: 'teun@easypos.nl',
    password: 'teun4psv'
  }
  const authTokenCreateSuccessfulResponse = {
    type: constants.RECEIVE_USER_TOKEN_CREATE,
    json: {
      success: true,
      token: 'qicXyn6BhYhyoBuA_SFoZtTDN'
    },
    payload: {
      subdomain: 'test-teun',
      username: 'teun@easypos.nl',
      token: 'qicXyn6BhYhyoBuA_SFoZtTDN'
    }
  }
  const authTokenCreateFailedResponse = {
    type: constants.RECEIVE_USER_TOKEN_CREATE,
    json: {
      success: false,
      reason: "Ongeldige gebruikersnaam of wachtwoord!"
    },
    payload: {
      subdomain: 'test-teun',
      username: 'teun@easypos.nl'
    }
  }

  beforeEach(() => {
    fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse)
  })

  afterEach(() => {
    fetchMock.restore()
  })

  it('Should return a route configuration object', () => {
    expect(typeof _route).to.equal('object')
  })

  it('Should define a route component', () => {
    expect(_route.path).to.equal('sign_in')
  })

  const middlewares = [ thunk ]
  const mockStore = configureMockStore(middlewares)

  it('Should trigger RECEIVE_USER_TOKEN_CREATE action containing a token on a successful login attempt', () => {
    //fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse)
    const expectedActions = [
      {
        type: constants.REQUEST_USER_TOKEN_CREATE,
        payload: authTokenCreateSuccessfulRequest
      },
      authTokenCreateSuccessfulResponse
    ]
    const store = mockStore({ user: { isFetching: false } })

    return store.dispatch(fetchToken(authTokenCreateSuccessfulRequest))
      .then((data) => {
        console.log(store.getActions()[1])
        // console.log(expectedActions[1])
        expect(_.isEqual(store.getActions(), expectedActions)).to.equal(true)
      })
  })
})

我可能会注意到的另一件事是,我昨天进行了这项测试,但是从那时起我修改了我的Redux状态的结构,似乎已经破坏了一些东西...... :(回顾我的Git历史并没有帮助我有这个烦人的事情。

我希望有人能指出我在这里正确的方向,这真的有助于我和我的心灵平静。提前一堆谢谢!

1 个答案:

答案 0 :(得分:0)

叹息......我发现了我的愚蠢错误。 fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/‌​v1/auth_tokens/creat‌​e', authTokenCreateSuccessfulResponse) 应该 fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/‌​v1/auth_tokens/creat‌​e', authTokenCreateSuccessfulResponse.payload)