从获取请求返回的 JSON 在测试和开发中不同
Returned JSON from fetch requests differs in test and dev
我希望我的问题标题足够易于理解。我真的想不出更好的措辞方式,字符数限制让我崩溃了。
我遇到的问题发生在我正在处理的项目中,该项目使用 React、Redux 和 react-router-redux 和 redux-auth-wrapper 等软件包。
为了进行测试,我将 Karma 测试运行器与 Enzyme、Sinon 和 Chai 一起使用。在测试中,我使用 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))
}
)
当我在我的开发代码中调度这个动作时,它工作得很好!此 returns 以下响应:
{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'}}
因此,代码 returns 没有返回正确的响应,而是一个完整的 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 历史并没有帮助我解决这个烦人的事情。
我希望有人能在这里为我指明正确的方向,这真的会帮助我和我内心的平静。提前致谢!
唉...我发现了我的愚蠢错误。
fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse)
应该
fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse.payload)
我希望我的问题标题足够易于理解。我真的想不出更好的措辞方式,字符数限制让我崩溃了。
我遇到的问题发生在我正在处理的项目中,该项目使用 React、Redux 和 react-router-redux 和 redux-auth-wrapper 等软件包。
为了进行测试,我将 Karma 测试运行器与 Enzyme、Sinon 和 Chai 一起使用。在测试中,我使用 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))
}
)
当我在我的开发代码中调度这个动作时,它工作得很好!此 returns 以下响应:
{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'}}
因此,代码 returns 没有返回正确的响应,而是一个完整的 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 历史并没有帮助我解决这个烦人的事情。
我希望有人能在这里为我指明正确的方向,这真的会帮助我和我内心的平静。提前致谢!
唉...我发现了我的愚蠢错误。
fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse)
应该
fetchMock.mock('http://test-teun.easyposonline.dev:3000/api/v1/auth_tokens/create', authTokenCreateSuccessfulResponse.payload)