Using Jasmines spyon in a private method

Is it possible to use the Jasmine unit testing platform Spyon method on private class methods?

The documentation gives this example, but can it be flexible for a private function?

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

Just add the generic <any> parameter to the spyon () function:

  spyOn<any>(fakePerson, 'sayHello'); 

It works great!

+84
source

if you use Typescript for your objects, the function is not really private.
All you need to do is save the value returned from the spyOn call and then request its calls property.

In the end, this code should work fine for you (at least it worked for me):

 describe("Person", function() { it("calls the sayHello() function", function() { var fakePerson = new Person(); // save the return value: var spiedFunction = spyOn<any>(fakePerson, "sayHello"); fakePerson.helloSomeone("world"); // query the calls property: expect(spiedFunction.calls.any()).toBeFalsy(); }); }); 
+4
source

Typescript is compiled in javascript, and in javascript, each method is public. Thus, you can use the index entry of the array to access private methods or files, namely:

 Object['private_field'] 
+2
source

There is no reason why you cannot access a private function outside the context of your instance.

Btw, it is not a good idea to spy on objects that you want to check. When you check to see if any particular method in your class is called that you want to test, it says nothing. Suppose you wrote a test and it passed, after two weeks you refactor some things in a function and add an error. So your test is still green because you are calling the function. IN

Spies are useful when you work with Dependency Injection , where all external dependencies are passed by the constructor and not created in your class. So let's say that you have a class that needs a dom element. Normal to use this element in jquery selector. But how do you want to verify that something is done with this element? Of course, you can add it to your html test pages. But you can also call your class by passing an element in the constructor. That way, you can use a spy to check if your class interacts with this element as you expected.

+1
source

In my case (typewriting):

 jest.spyOn<any, string>(authService, 'isTokenActual') 

OR with fake result:

 jest.spyOn<any, string>(authService, 'isTokenActual').mockImplementation(() => { return false; }); 
+1
source

If you want to test private functions inside a class, why not add a constructor to your class that signals the return of these private functions?

Read this to understand what I mean: http://iainjmitchell.com/blog/?p=255

I use a similar idea and it still works great!

0
source

Let's say sayHello(text: string) is a private method. You can use the following code:

 // 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'); 
  • Create a spy method with any .
  • To access a private (or protected) method, use the [] operator.
-1
source

Source: https://habr.com/ru/post/903591/


All Articles