Sinon Spy 从来没有打过电话,但应该是
Sinon Spy never called but it should be
问题
我正在使用 Jest 和 SinonJS 测试自定义 redux 中间件,更准确地说,我想测试是否在中间件内的特殊条件下调用某些函数。
我使用 SinonJS 创建间谍,我 运行 我使用 Jest 进行测试。我为要跟踪的特定功能初始化了间谍,当我检查间谍是否已被调用时,即使应该被调用,间谍也没有被调用(手动测试)。
代码
这是我要测试的中间件:
import { Cookies } from 'react-cookie';
import setAuthorizationToken from './setAuthorizationToken';
let cookies = new Cookies();
export const bindTokenWithApp = (store) => (next) => (action) => {
// Select the token before action
const previousToken = getToken(store.getState());
// Dispatch action
const result = next(action);
// Select the token after dispatched action
const nextToken = getToken(store.getState());
if (previousToken !== nextToken) {
if (nextToken === '') {
setAuthorizationToken(false);
cookies.remove(SESSION_COOKIE_NAME, COOKIE_OPTIONS);
} else {
cookies.set(SESSION_COOKIE_NAME, nextToken, COOKIE_OPTIONS);
setAuthorizationToken(nextToken);
}
}
return result;
};
这是我的实际测试
import { bindTokenWithApp } from './middleware';
import { Cookies } from 'react-cookie';
import sinon, { assert } from 'sinon';
import setAuthorizationToken from './setAuthorizationToken';
describe('bindTokenWithApp', () => {
const next = jest.fn();
const action = jest.fn();
let cookies = new Cookies();
it('removes cookies when there is no token', () => {
// My actual not working spies
const cookieSpy = sinon.spy(cookies.remove);
const authSpy = sinon.spy(setAuthorizationToken);
// Stub for the specific case. This code works,
// I console.logged in the middleware and I'm getting the below values
const getState = sinon.stub();
getState.onFirstCall().returns({ auth: { token: 'a token' } });
getState.onSecondCall().returns({ auth: { token: '' } });
const store = { getState: getState };
bindTokenWithApp(store)(next)(action);
assert.calledOnce(cookieSpy);
assert.calledOnce(authSpy);
// Output : AssertError: expected remove to be called once but was called 0 times
// AssertError: expected setAuthorizationToken to be called once but was called 0 times
cookieSpy.restore(); // <= This one works
authSpy.restore(); // TypeError: authSpy.restore is not a function
});
});
我已经阅读了 SinonJS 文档和一些 Whosebug 帖子,但没有解决方案。我也打不通authSpy.restore();
。我想我没有以正确的方式初始化间谍,我误解了 SinonJS 中的一个概念,但我找不到哪个!
The setAuthorizationToken signature is
(alias) const setAuthorizationToken: (token: any) => void
import setAuthorizationToken
I think it's a classical module so I can't figure out why I struggle with authSpy.restore();
您的两个间谍实际上有两个不同的修复程序,它们都存在相同的潜在问题。 sinon.spy(someFunction)
实际上并没有包装 someFunction
本身,它 returns 是它的间谍但不执行任何替换。
对于第一个间谍,存在一个shorthand自动包装对象的方法:sinon.spy(cookie, 'remove')
应该做你需要的。
对于第二个间谍,它更复杂,因为您需要将间谍包裹在 setAuthorizationToken
的默认导出周围。为此,您将需要类似 proxyquire 的东西。 Proxyquire 是一种专门的需求机制,允许您用所需的测试方法替换导入。以下是您需要执行的操作的简要说明:
const authSpy = sinon.spy(setAuthorizationToken);
bindTokenWithApp = proxyquire('./middleware', { './setAuthorizationToken': authSpy});
问题
我正在使用 Jest 和 SinonJS 测试自定义 redux 中间件,更准确地说,我想测试是否在中间件内的特殊条件下调用某些函数。
我使用 SinonJS 创建间谍,我 运行 我使用 Jest 进行测试。我为要跟踪的特定功能初始化了间谍,当我检查间谍是否已被调用时,即使应该被调用,间谍也没有被调用(手动测试)。
代码
这是我要测试的中间件:
import { Cookies } from 'react-cookie';
import setAuthorizationToken from './setAuthorizationToken';
let cookies = new Cookies();
export const bindTokenWithApp = (store) => (next) => (action) => {
// Select the token before action
const previousToken = getToken(store.getState());
// Dispatch action
const result = next(action);
// Select the token after dispatched action
const nextToken = getToken(store.getState());
if (previousToken !== nextToken) {
if (nextToken === '') {
setAuthorizationToken(false);
cookies.remove(SESSION_COOKIE_NAME, COOKIE_OPTIONS);
} else {
cookies.set(SESSION_COOKIE_NAME, nextToken, COOKIE_OPTIONS);
setAuthorizationToken(nextToken);
}
}
return result;
};
这是我的实际测试
import { bindTokenWithApp } from './middleware';
import { Cookies } from 'react-cookie';
import sinon, { assert } from 'sinon';
import setAuthorizationToken from './setAuthorizationToken';
describe('bindTokenWithApp', () => {
const next = jest.fn();
const action = jest.fn();
let cookies = new Cookies();
it('removes cookies when there is no token', () => {
// My actual not working spies
const cookieSpy = sinon.spy(cookies.remove);
const authSpy = sinon.spy(setAuthorizationToken);
// Stub for the specific case. This code works,
// I console.logged in the middleware and I'm getting the below values
const getState = sinon.stub();
getState.onFirstCall().returns({ auth: { token: 'a token' } });
getState.onSecondCall().returns({ auth: { token: '' } });
const store = { getState: getState };
bindTokenWithApp(store)(next)(action);
assert.calledOnce(cookieSpy);
assert.calledOnce(authSpy);
// Output : AssertError: expected remove to be called once but was called 0 times
// AssertError: expected setAuthorizationToken to be called once but was called 0 times
cookieSpy.restore(); // <= This one works
authSpy.restore(); // TypeError: authSpy.restore is not a function
});
});
我已经阅读了 SinonJS 文档和一些 Whosebug 帖子,但没有解决方案。我也打不通authSpy.restore();
。我想我没有以正确的方式初始化间谍,我误解了 SinonJS 中的一个概念,但我找不到哪个!
The setAuthorizationToken signature is
(alias) const setAuthorizationToken: (token: any) => void
import setAuthorizationTokenI think it's a classical module so I can't figure out why I struggle with
authSpy.restore();
您的两个间谍实际上有两个不同的修复程序,它们都存在相同的潜在问题。 sinon.spy(someFunction)
实际上并没有包装 someFunction
本身,它 returns 是它的间谍但不执行任何替换。
对于第一个间谍,存在一个shorthand自动包装对象的方法:sinon.spy(cookie, 'remove')
应该做你需要的。
对于第二个间谍,它更复杂,因为您需要将间谍包裹在 setAuthorizationToken
的默认导出周围。为此,您将需要类似 proxyquire 的东西。 Proxyquire 是一种专门的需求机制,允许您用所需的测试方法替换导入。以下是您需要执行的操作的简要说明:
const authSpy = sinon.spy(setAuthorizationToken);
bindTokenWithApp = proxyquire('./middleware', { './setAuthorizationToken': authSpy});