Jasmine spy没有存根这个函数
Jasmine spyOn doesn't stub the function
我正在尝试使用
来存根函数import * as tooltip from './tooltip';
describe('tooltip', () => {
it('should ...', () => {
// arrange
spyOn(tooltip, 'createTooltip');
...
tooltip.tooltip.inserted(...); // calls createTooltip inside
...
expect(tooltip.createTooltip).toHaveBeenCalledWith(...); // assert called with
});
});
但是当inserted
被调用时,createTooltip
的真正实现被调用,assert抛出错误消息:
Expected spy createTooltip to have been called with ... but it was never called.
更新1:完整的工具提示指令代码:
import $ from "jquery";
import classes from '../../css/directives/tooltip.scss';
const TOOLTIP_CLASS = classes.tooltip;
const TOOLTIP_ARROW_CLASS = classes.arrow;
const TOOLTIP_ARROW_BORDER_WIDTH = 5;
const TOOLTIP_DEFAULT_MARGIN = 2;
const TOOLTIP_DEFAULT_BACKGROUND_COLOR = 'rgba(0, 0, 0, .8)';
const TOOLTIP_DEFAULT_FADE_SPEED = 'slow';
const TOOLTIP_DEFAULT_POSITION = 'right';
const POSITION_FN = {
top: positionTooltipToTop,
left: positionTooltipToLeft,
right: positionTooltipToRight,
bottom: positionTooltipToBottom
};
export const tooltip = {
inserted: (el, binding) => {
const $body = $('body');
const $el = $(el);
const $tooltip = createTooltip($body, $el, binding);
$el.mouseenter(() => {
$tooltip
.stop()
.hide()
.appendTo($body)
.fadeIn(TOOLTIP_DEFAULT_FADE_SPEED || binding.value.fade);
});
$el.mouseleave(() => {
$tooltip
.stop()
.fadeOut(TOOLTIP_DEFAULT_FADE_SPEED || binding.value.fade, () => {
$tooltip.detach();
});
});
}
};
export function createTooltip($body, $el, binding) {
console.log('in function createTooltip');
const $arrow = createTooltipArrow();
const $tooltip = $(document.createElement('span'));
$tooltip.html(binding.value.message);
$tooltip.append($arrow);
if (binding.value.color) {
$tooltip.css('color', binding.value.color);
}
if (binding.value.backgroundColor) {
$tooltip.css('background-color', binding.value.backgroundColor);
}
$tooltip.addClass(TOOLTIP_CLASS);
$body.append($tooltip);
POSITION_FN[binding.value.position || TOOLTIP_DEFAULT_POSITION]($el, $tooltip, $arrow, binding);
$tooltip.detach();
return $tooltip;
}
export function createTooltipArrow() {
const $arrow = $(document.createElement('span'));
$arrow.addClass(TOOLTIP_ARROW_CLASS);
return $arrow;
}
export function positionTooltipToTop($el, $tooltip, $arrow, binding) {
$tooltip.css({
top: $el.offset().top - $tooltip.outerHeight() - (TOOLTIP_ARROW_BORDER_WIDTH + (binding.value.margin || TOOLTIP_DEFAULT_MARGIN)),
left: $el.offset().left + ($el.outerWidth() / 2) - ($tooltip.outerWidth() / 2)
});
$arrow.css({
top: '100%',
left: '50%',
marginLeft: -1 * TOOLTIP_ARROW_BORDER_WIDTH,
borderTopColor: binding.value.backgroundColor || TOOLTIP_DEFAULT_BACKGROUND_COLOR
});
}
export function positionTooltipToRight($el, $tooltip, $arrow, binding) {
$tooltip.css({
top: $el.offset().top + ($el.outerHeight() / 2) - ($tooltip.outerHeight() / 2),
left: $el.offset().left + $el.outerWidth() + TOOLTIP_ARROW_BORDER_WIDTH + (binding.value.margin || TOOLTIP_DEFAULT_MARGIN)
});
$arrow.css({
top: '50%',
right: '100%',
marginTop: -1 * TOOLTIP_ARROW_BORDER_WIDTH,
borderRightColor: binding.value.backgroundColor || TOOLTIP_DEFAULT_BACKGROUND_COLOR
});
}
export function positionTooltipToLeft($el, $tooltip, $arrow, binding) {
$tooltip.css({
top: $el.offset().top + ($el.outerHeight() / 2) - ($tooltip.outerHeight() / 2),
left: $el.offset().left - $tooltip.outerWidth() - (TOOLTIP_ARROW_BORDER_WIDTH + (binding.value.margin || TOOLTIP_DEFAULT_MARGIN))
});
$arrow.css({
top: '50%',
left: '100%',
marginTop: -1 * TOOLTIP_ARROW_BORDER_WIDTH,
borderLeftColor: binding.value.backgroundColor || TOOLTIP_DEFAULT_BACKGROUND_COLOR
});
}
export function positionTooltipToBottom($el, $tooltip, $arrow, binding) {
$tooltip.css({
top: $el.offset().top + $el.outerHeight() + TOOLTIP_ARROW_BORDER_WIDTH + (binding.value.margin || TOOLTIP_DEFAULT_MARGIN),
left: $el.offset().left + ($el.outerWidth() / 2) - ($tooltip.outerWidth() / 2)
});
$arrow.css({
bottom: '100%',
left: '50%',
marginLeft: -1 * TOOLTIP_ARROW_BORDER_WIDTH,
borderBottomColor: binding.value.backgroundColor || TOOLTIP_DEFAULT_BACKGROUND_COLOR
});
}
我的解决方案:
我使用babel-plugin-rewire作为我的构建过程的一部分,我可以在没有di的情况下测试指令,这对我来说没有多大意义。
测试代码:
import $ from 'jquery';
import { tooltip, __RewireAPI__ as TooltipRewireAPI } from './tooltip';
describe('tooltip', () => {
const createTooltipSpy = jasmine.createSpy('createTooltipSpy');
beforeEach(() => {
TooltipRewireAPI.__Rewire__('createTooltip', createTooltipSpy);
});
afterEach(() => {
TooltipRewireAPI.__ResetDependency__('createTooltip');
});
it('should have mouseenter and mouseleave event listeners', () => {
const $body = $('body');
const el = document.createElement('div');
const binding = {};
const $el = $(el);
tooltip.inserted(el, binding);
expect(createTooltipSpy).toHaveBeenCalledWith($body, $el, binding);
expect($el.mouseenter).toEqual(jasmine.any(Function));
expect($el.mouseleave).toEqual(jasmine.any(Function));
});
});
相关文章:
- 如何在角度指令规范中使用 jasmine 存根 jquery 函数
- 如何使用jasmine AJAX存根AJAX函数
- sinon 存根嵌套在描述/请求函数中
- Sinon-带有回调的存根函数-导致测试方法超时
- 在sinon中存根嵌套函数调用
- 在对揭示模块进行单元测试时,如何存根私有函数
- 在 ES7 中存根类字段函数
- Javascript测试存根全局变量函数
- 如何使用simon .js存根链接函数
- 如何将从外部作用域调用的方法存根到被测函数
- 我如何使用sinon存根函数为neo4j Thingdom模块
- Jasmine spy没有存根这个函数
- 当断言函数调用时,chaispy不能识别Sinon存根函数
- 断言参数与存根函数至少匹配一个列表中的值
- 对TypeScript中闭包中的函数进行存根处理
- 加载 jQuery 后如何访问存根美元函数
- 函数内部的存根函数调用
- es6模块中其他函数使用的存根函数
- 存根函数在被其他函数调用时没有返回正确的值
- 存根函数只有一个参数