Javascript 在私有方法上使用Jasmines spyon

Javascript 在私有方法上使用Jasmines spyon,javascript,unit-testing,jasmine,Javascript,Unit Testing,Jasmine,可以在类私有方法上使用Jasmine单元测试框架的spyon方法吗 文档中给出了这个示例,但是对于私有函数,这个示例是否灵活 describe("Person", function() { it("calls the sayHello() function", function() { var fakePerson = new Person(); spyOn(fakePerson, "sayHello"); fakePerson.hello

可以在类私有方法上使用Jasmine单元测试框架的spyon方法吗

文档中给出了这个示例,但是对于私有函数,这个示例是否灵活

describe("Person", function() {
    it("calls the sayHello() function", function() {
        var fakePerson = new Person();
        spyOn(fakePerson, "sayHello");
        fakePerson.helloSomeone("world");
        expect(fakePerson.sayHello).toHaveBeenCalled();
    });
});

没有原因您不能访问实例上下文之外的私有函数

顺便说一句,监视你想测试的对象不是个好主意。当您测试您想要测试的类中的特定方法是否被调用时,它什么也没说。假设您编写了测试并通过了测试,两周后您重构了函数中的一些内容并添加了一个bug。所以您的测试仍然是绿色的,因为您调用了函数。B


SPIE在使用时非常有用,因为所有外部依赖项都是由构造函数传递的,而不是在类中创建的。假设您有一个需要dom元素的类。通常,您会在类中使用jquery选择器来获取此元素。但是你想如何测试用这个元素做了什么?当然你可以把它添加到你的html测试页面。但是,您也可以通过构造函数中的元素调用您的类。这样,您就可以使用spy来检查您的类是否如您所期望的那样与该元素交互。

如果您想测试类中的私有函数,为什么不向类中添加一个构造函数来指示这些私有函数已返回

通读一下我的意思:


我一直在使用一个类似的想法,到目前为止,它的工作非常好

如果对对象使用Typescript,则该函数实际上不是私有的。
您只需保存从
spyOn
call返回的值,然后查询它的
calls
属性

最后,这段代码对您来说应该很好(至少对我来说是这样):

描述(“人”,函数(){
它(“调用sayHello()函数”,function()){
var fakePerson=新人员();
//保存返回值:
var spiedFunction=spyOn(冒牌货,“sayHello”);
伪造者。helloSomeone(“世界”);
//查询calls属性:
expect(spiedFunction.calls.any()).toBeFalsy();
});
});

只需在spyon()函数中添加一个通用参数

 spyOn<any>(fakePerson, 'sayHello');
spyOn(冒牌货,'sayHello');

它工作得很好

Typescript被编译成javascript,在javascript中,每个方法都是公共的。因此,您可以使用数组索引表示法访问私有方法或文件,即:

Object['private_field']
在我的情况下(Typescript):

jest.spyOn(authService,'isTokenActual')
或者以模拟的结果:

jest.spyOn<any, string>(authService, 'isTokenActual').mockImplementation(() => {
  return false;
});
jest.spyOn(authService,'isTokenActual').mockImplementation(()=>{
返回false;
});
比如说
sayHello(text:string)
是一个私有方法。您可以使用以下代码:

// Create a spy on it using "any"
spyOn<any>(fakePerson, 'sayHello').and.callThrough();

// To access the private (or protected) method use [ ] operator:
expect(fakeperson['sayHello']).toHaveBeenCalledWith('your-params-to-sayhello');
//使用“any”在其上创建间谍
spyOn(冒牌人,'sayHello')。和.callThrough();
//要访问私有(或受保护)方法,请使用[]运算符:
期望(冒牌货['sayHello'])。与('your-params-to-sayHello')一起被调用;
  • 使用
    any
    创建一个spy-on-private方法
  • 要访问私有(或受保护)方法,请使用
    []
    运算符
间谍(冒牌人,'sayHello');
期望(冒牌货['sayHello'])。被调用();
通过将
添加到spyOn,您可以将其从typescript类型检查中删除。 您还需要使用数组索引表示法来访问测试expect中的私有方法(sayHello)(组件“privateMethod”);
const spy = spyOn<any>(component, 'privateMethod');
expect(spy).toHaveBeenCalled();
期望(间谍)。已被调用();
为了避免关于通过字符串文本访问对象的lint警告,请创建spy对象的本地常量。

如果发布privat方法,它就不再是privat。顺便说一句,正如我在回答中所描述的,测试privat方法没有多大意义。我们可以同意,但不同意。我们的javascript代码库非常庞大,我们只在一些类上公开了一小部分公共函数/属性。在这些私有函数中处理了很多逻辑。我只公开一个私有方法,以便测试框架可以访问它。如果未正确调用构造函数,则不会返回私有函数。说“监视要测试的对象不是一个好主意”是不正确的。间谍的使用并不局限于检查函数是否被简单调用,仅此而已。您可以使用spies检查返回值,完全替换测试用例的函数,抛出错误等。我建议您阅读jasmine文档以获得更完整的理解。spies不是一个好主意!??你大错特错了!是的,我同意蒂姆的观点,你应该看看文件,谁投的票?!我不是这么说的。使用间谍是可以的。但是你应该把你想测试的对象当作一个黑盒子来处理。只测试进出的东西。不要测试黑匣子的内部,若你们监视被测试对象的方法,你们会怎么做。因此,监视传入对象的回调是完全正确的。如果尝试调用未导出(私有)函数,则会出现类型错误:
error:(33,56)TS2345:类型为“sayHello”的参数不可分配给类型为“say再见”的参数“.
其中,
saybeaye
Person
上的公共方法,
saybeaye
是私有方法。我必须将其转换为任何(“sayHello”作为任何内容)我需要更多的上下文,看起来您的任务不起作用,无法访问私有函数。但是试着像这样访问它:
person[“sayHello”]
而不是
person.sayHello
(如果你是这样做的话)。这不是最佳做法,但在极少数情况下是可以原谅的;)同意@FlavorScape。Typescript(至少1.7及更高版本)希望spied on finction是公共的,因为sayHello不是类型Say再见(或任何其他公共函数),它将抛出一个错误。我只能用上面列出的间谍来解决这个问题。这似乎是一件好事
spyOn<any>(fakePerson, 'sayHello');
expect(fakePerson['sayHello']).toHaveBeenCalled();
const spy = spyOn<any>(component, 'privateMethod');
expect(spy).toHaveBeenCalled();