Jasmine Spies.and.stub method

26,066

Solution 1

For the term, you can look at wikipedia : http://en.wikipedia.org/wiki/Test_stub

In a nutshell it's a "fake" object that you can control that replaces a "real" object in your code.

For the function, what I understand is that and.stub() removes the effect of and.callThrough() on a spy.

When you call and.callThrough, the spy acts as a proxy, calling the real function, but passing through a spy object allowing you to add tests like expectation.

When you call and.stub, or if you never call and.callThrough, the spy won't call the real function. It's really usefull when you don't want to test an object's behavior, but be sure that it was called. Helping you to keep your test truly unitary.

Solution 2

To complete the previous answer:

Indeed, it's not clear from the doc, but it's very clear in the source code:

https://github.com/jasmine/jasmine/blob/4be20794827a63ca5295848c58ffc478624ee4dc/src/core/SpyStrategy.js

plan = function() {};

-> the called function is empty

this.callThrough = function() {
  plan = originalFn;

-> the called function is the original function

this.stub = function(fn) {
  plan = function() {};

-> the called function is empty (again)

Share:
26,066

Related videos on Youtube

Ratko
Author by

Ratko

Updated on August 23, 2022

Comments

  • Ratko
    Ratko almost 2 years

    I've been reading through the Jasmine documentation and I've been struggling to understand what the Spies .and.stub method actually does. English is not my native language, so I don't even know what the word "stub" actually means, and there is no translation for it in my language.

    In the documentation it says:

    When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub.

    describe("A spy", function() {  
    
    var foo, bar = null;
    
      beforeEach(function() {
        foo = {
          setBar: function(value) {
            bar = value;
          }
        };
    
        spyOn(foo, 'setBar').and.callThrough();
      });
    
      it("can call through and then stub in the same spec", function() {
        foo.setBar(123);
        expect(bar).toEqual(123);
    
        foo.setBar.and.stub();
        bar = null;
    
        foo.setBar(123);
        expect(bar).toBe(null);
      });
    });
    

    What does and.stub actually do and how is it useful?

  • Ratko
    Ratko over 9 years
    Thank you very much. The fact that the and.stub() removes the effect of and.callThrough() is what's missing on their documentation. It really explains everything.
  • aycanadal
    aycanadal over 5 years
    How is it different then spyOn(foo, 'setBar') without .and.callThrough()?
  • Manu Chadha
    Manu Chadha over 5 years
    agree with aycanadal. What is the use of stub as just spyOn seems to do the same thing. if I do spyOn(foo,'setBar'), setBar's original implementation will not be called. In fact it seems, stub is same as calling and.callFake(()=>{})
  • Boris Charpentier
    Boris Charpentier over 5 years
    jasmine mix the concept of spy and stub in it's syntax. A stub replace the implementation where a spy only act has a passthrough calling the actual implementation. To have a real spy you need to do spyOn(..).and.callThrough(). But you can re-enable the stub with and.stub after calling callThrough. Agreed it's mainly sugar ! and.callFake has a similar result.
  • coppereyecat
    coppereyecat almost 3 years
    @ManuChadha You may know this by now, but in case someone reading these comments is still confused: the point is to have a way to reset the spy to the default behavior after you have changed the behavior of the spy with .and.callThrough() or and.callFake(), etc, for a given test, for example if you do not want the call through or call fake behavior on other tests running with that spy.