Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript SpyOn单独导出ES6函数_Javascript_Unit Testing_Ecmascript 6_Jasmine - Fatal编程技术网

Javascript SpyOn单独导出ES6函数

Javascript SpyOn单独导出ES6函数,javascript,unit-testing,ecmascript-6,jasmine,Javascript,Unit Testing,Ecmascript 6,Jasmine,tl;医生: 我用茉莉花 我想测试aaa函数,该函数从同一位置调用bbb 模块 我想监视bbb,但最终aaa称为 原始的bbb功能,不是间谍 我如何强制aaa呼叫间谍? 模块: export function aaa() { return bbb(); } export function bbb() { return 222; } 测试: import * as util from 'my-module'; describe('aaa test', () => { le

tl;医生:

  • 我用茉莉花
  • 我想测试
    aaa
    函数,该函数从同一位置调用
    bbb
    模块
  • 我想监视
    bbb
    ,但最终
    aaa
    称为 原始的
    bbb
    功能,不是间谍 我如何强制
    aaa
    呼叫间谍?

    模块:

    export function aaa() {
      return bbb();
    }
    
    export function bbb() {
      return 222;
    }
    
    测试:

    import * as util from 'my-module';
    
    describe('aaa test', () => {
    
      let bbbSpy: Spy;
    
      beforeEach(() => {
        bbbSpy = spyOn(util, 'bbb');
      });
    
      it('should return SPYED', () => {
        bbbSpy.and.returnValue('SPYED!!');
        const result = util.aaa();
        expect(result).toEqual('SPYED!!'); // Doesn't work - still 222
      });
    
    });
    
    所以,基本上这是行不通的。有人能帮我吗


    p.S.我不想更改模块的代码,因为在这种情况下,我必须更改项目中大量的代码。我需要一个测试的通用解决方案。

    即使是不同的框架,也有一个相关的问题可以告诉您为什么这不起作用:。基本上,您将无法访问该函数的固定引用,而是要明确该函数与模块上下文中的函数相同

    我知道这并不能满足你在问题中提出的限制条件,但它只是表明你想通过使用spy实现的目标是不可能的


    使用JavaScript,无法交换对某些内容的引用。不能调出模块内部的函数。在您的示例中,当您尝试使用spyOn.and.returnValue覆盖bbb时,您只是在测试中修改了本地绑定bbb,但它对其他文件中的bbb绑定没有影响。

    编写代码时没有考虑到测试问题,如果不进行重构,它将无法获得完全覆盖

    在这种情况下,不可能强制
    aaa
    呼叫间谍。直接指模块范围内的
    bbb
    功能。没有可监视的对象

    这基本上与JavaScript作用域问题相同:

    (() => {
      var bar = 1; // there's no way to reach this variable from the outside
    })();
    
    如果函数始终被称为对象属性,则可以这样做。ES模块中没有这样的对象,但这种方法在CommonJS模块中很常见,特别是出于可测试性的考虑(像Webpack这样的捆绑工具都支持):

    通过这种方式,
    bbb
    属性可以通过
    spyOn(util,'bbb')
    监视
    *
    导入,如原始代码所示。这不适用于具有只读导出且不与CommonJS模块互操作的本机ES模块


    如果
    aaa
    bbb
    驻留在不同的模块中,那么这样做可能更容易。这样就有可能模拟模块(这不适用于本机ES模块)。

    @Rajesh Nope。我的意思是
    aaa
    按原样调用
    bbb()
    ,而不是
    util.bbb()
    。我无法遍历所有代码并更改所有函数以使用这种方式。此外,在这种情况下,模块的函数不会单独导出。@Rajesh实际上不起作用,但感谢答案是正确的,为了测试它,您要么进行重构,要么不在这里使用spy,只测试函数aaa()的输出,也就是说,如果代码是功能性的,那么在这种情况下意味着对bbb()的调用影响返回值,而不仅仅是像登录控制台这样的副作用。
    exports.aaa = function aaa() {
      return exports.bbb();
    }
    
    exports.bbb = function bbb() {
      return 222;
    }