如何在 karma angularjs 中对 setInterval 进行单元测试 [英] how to unit-test setInterval in karma angularjs

查看:22
本文介绍了如何在 karma angularjs 中对 setInterval 进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

app.directive('shuffleBlocks', function($timeout){返回 {链接:函数(sco,ele,att){如果(itemCnt <= 1)返回;/*触发函数*/函数触发器事件(){...}ele.bind('click', triggerEvent);setInterval(triggerEvent, 5000);}}})

这里是我写的测试

 var elem = '

';elem = mockCompile(elem)(rootScope.$new());设置间隔(函数(){期望(......).toBe(....)});

显然这不是正确的方法,有谁知道如何在业力中测试 $timeout 和 setInterval?

解决方案

UPDATE: 在 angular 1.2+ 应用程序中模拟 setInterval 的正确方法是使用 angular 的 $interval 服务.使用 $interval 服务提供了许多好处,但在这种情况下最常用的方法之一是 $interval.flush() 方法.在编写测试时,$interval 公开了一个 .flush() 方法,该方法允许您模拟 JS 时钟.

app.directive('shuffleBlocks', function($timeout, $interval){返回 {链接:函数(sco,ele,att){如果(itemCnt <= 1)返回;/*触发函数*/函数 triggerEvent(){ ... }ele.bind('click', triggerEvent);$interval(triggerEvent, 5000);}}});

然后在您的单元测试中:

var elem = '

';elem = mockCompile(elem)(rootScope.$new());$interval.flush(5000);//刷新接受要刷新的毫秒数期望(......).toBe(....);

希望这对将来查找此答案的任何人都有帮助.对于仍在使用 1.1X 的人,我会留下我之前的答案.

<小时>

上一个答案:根据 jasmine 文档,您应该能够仅使用 jasmine.Clock.useMock() 函数来模拟典型的 javascript 时钟并手动完成间隔.由于 angular 只是包装了本机 setTimeout 函数,我很肯定它应该允许它工作,尽管我还没有测试过它.

1.3 版的 jasmine 文档位于此处.下面是演示其工作原理的代码示例.

beforeEach(function() {timerCallback = jasmine.createSpy('timerCallback');jasmine.Clock.useMock();});it("导致同步调用超时", function() {设置超时(函数(){定时器回调();}, 100);期望(定时器回调).not.toHaveBeenCalled();茉莉花时钟滴答声(101);期望(定时器回调).toHaveBeenCalled();});

我看到的唯一问题是你的 triggerEvent() 函数是你的链接函数的本地函数,所以我不知道你如何能够得到它来模拟它.但希望这为您指明了正确的方向.如果没有,抱歉,我试过了.

更新:模拟时钟的语法在 Jasmine 2.0 中发生了变化.如果您使用的是 2.0,请在此处查看更新的文档.>

app.directive('shuffleBlocks', function($timeout){
    return {
        link: function(sco,ele,att){
            if (itemCnt <= 1) return;

            /*Trigger function*/
            function triggerEvent(){
                ...
            }
            ele.bind('click', triggerEvent);

            setInterval(triggerEvent, 5000);
        }
    }
})

here I wrote the test

        var elem = '<div shuffle-blocks><div>';
        elem = mockCompile(elem)(rootScope.$new());
        setInterval(function(){
            expect(......).toBe(....)
        });

Obviously this is not the right method, does anyone know how to test $timeout and setInterval in karma?

解决方案

UPDATE: The proper method of mocking setInterval in an angular 1.2+ application is to use angular's $interval service. Using the $interval service provides a number of benefits, but the one of most use in this situation is the $interval.flush() method. When writing tests, $interval exposes a .flush() method which allows you to mock the JS clock.

app.directive('shuffleBlocks', function($timeout, $interval){
    return {
        link: function(sco,ele,att){
            if (itemCnt <= 1) return;

            /*Trigger function*/
            function triggerEvent(){ ... }
            ele.bind('click', triggerEvent);

            $interval(triggerEvent, 5000);
        }
    }
});

and then in your unit test:

var elem = '<div shuffle-blocks><div>';
elem = mockCompile(elem)(rootScope.$new());
$interval.flush(5000); // flush accepts the # of ms to be flushed
expect(......).toBe(....);

Hope that's helpful to anyone who looks up this answer in the future. I'll leave my previous answer for those still using 1.1X.


Previous Answer: According the jasmine docs, you should be able to just use the jasmine.Clock.useMock() function to mock the typical javascript clock and manually work your way through the interval. Since angular is just wrapping the native setTimeout function, I'm quite positive it should allow this to work, though I haven't tested it to be sure.

The jasmine docs for version 1.3 are here. Here's the code example that demonstrates how it works.

beforeEach(function() {
    timerCallback = jasmine.createSpy('timerCallback');
    jasmine.Clock.useMock();
});

it("causes a timeout to be called synchronously", function() {
    setTimeout(function() {
        timerCallback();
    }, 100);

    expect(timerCallback).not.toHaveBeenCalled();

    jasmine.Clock.tick(101);

    expect(timerCallback).toHaveBeenCalled();
});

The only issue I see is that your triggerEvent() function is local to your link function, so I don't know how you'll be able to get to it to mock it. But hopefully that points you in the right direction. If not, sorry, I tried.

UPDATE: The syntax for mocking the clock has changed in Jasmine 2.0. If you are using 2.0, please see the updated docs here.

这篇关于如何在 karma angularjs 中对 setInterval 进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆