Javascript: How to spy on superagent with Jasmine?
Asked Answered
D

4

8

I'm using the superagent ajax library for an app, and I'm trying to write some unit tests for it. I've got a class which looks like this:

someClass = {
  getData: function(){
    _this = this;
    superagent.get('/some_url').end(function(res){
      if(res.body){
        _this.data = res.body
      }
     });
   });
 }

How do I write a Jasmine test to spy on the _this.data = res.body call? Setting up a spy with and.callThrough() on getData isn't working. I don't want to actually call the URL in question; I'm just trying to test that if it gets data, it does something with it.

Thanks

Donoghue answered 18/12, 2014 at 19:28 Comment(1)
I'd like to point out that the title sounds like a question that some innocent young agent would ask as they try to figure out what some 00's mission is. Presumably, they named their microdrone Jasmine.Whoopee
S
3
spyOn(superagent, 'get').and.callFake(function(url) {
  return {
    end: function(cb) {
      //null for no error, and object to mirror how a response would look.
      cb(null, {body: data});
    }
  }
});
Suzannasuzanne answered 14/7, 2015 at 16:2 Comment(0)
B
0

Bror's answer works perfectly. To add something to his answer, when we need to add another superagent function (like set) to the spyOn method, you can use as follows.

spyOn(superagent, 'get').and.callFake(function(url) {
  return {
      set: function() {
        return {
          end: function(cb) {
            //null for no error, and object to mirror how a response would look.
            cb(null, {body: data});
          }
        }
     }
});

Here, the set function is used to set headers to the request.

Bechtold answered 7/8, 2015 at 11:50 Comment(1)
If we chain multiple methods like get().query().headers().timeout().end(), how do we spy on the inner most get call? Create a chain like the one you showed in the answer?Nabokov
V
0

There's another good solution here, which is to abstract out the anonymous function:

someClass = {
  getData: function(){
    _this = this;
    superagent.get('/some_url').end(this.handleAjax);
  },

  handleAjax: function(res){
    if(res.body){
      _this.data = res.body
    }
  }
}

Now you can test the handleAjax function discretely and with simple tests; and also stub superagent as you only need to check a method .end() is called on it with a particular value.

Anonymous functions are problematic for other reasons than just testing so this is a good refactor

Vedavedalia answered 25/4, 2017 at 10:25 Comment(0)
L
0

Say it's a patch, first make a mock patch return value:

this.mockPatchObject = {
      set: () => {
        return {
          end: (cb: any) => {
            cb(null, {body: 'etc'});
          },
        };
      },
    };

then return it as the value of patch:

this.superagentSpy = spyOn(request,'patch').and.returnValue(this.mockPatchObject);

then spy on the set function of the "mock" patch object:

this.superagentSetSpy = spyOn(this.mockPatchObject, 'set');
Lanna answered 6/7, 2017 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.