admin管理员组

文章数量:1290179

I have a Jasmine test that is failing because a random number is being generated and this random value is different for execution and spec.

fetch: function(options) {
    if(typeof options === "undefined") {
        options = {};
    }
    if(typeof options.data === "undefined") {
        options.data = {};
    }
    options.data.id = this.journalId;
    options.data.random = Math.floor(Math.random()*10000);
    col.prototype.fetch.call(this, options);
}

The test below fails because Math.floor(Math.random()*10000) is generating different values.

it("should call parent fetch with default options", function() {
  this.collection.fetch();
  expect(this.fetchSpy).toHaveBeenCalledWith({
    data: {
      id: 1,
      random: Math.floor(Math.random()*10000) 
    }
  }); 
});

Is there a way to make my test pass for cases where I have random numbers being generated?

I have a Jasmine test that is failing because a random number is being generated and this random value is different for execution and spec.

fetch: function(options) {
    if(typeof options === "undefined") {
        options = {};
    }
    if(typeof options.data === "undefined") {
        options.data = {};
    }
    options.data.id = this.journalId;
    options.data.random = Math.floor(Math.random()*10000);
    col.prototype.fetch.call(this, options);
}

The test below fails because Math.floor(Math.random()*10000) is generating different values.

it("should call parent fetch with default options", function() {
  this.collection.fetch();
  expect(this.fetchSpy).toHaveBeenCalledWith({
    data: {
      id: 1,
      random: Math.floor(Math.random()*10000) 
    }
  }); 
});

Is there a way to make my test pass for cases where I have random numbers being generated?

Share Improve this question asked Apr 1, 2013 at 22:34 HuyHuy 11.2k14 gold badges59 silver badges102 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

You're able to mock Math.random function. Jasmine 2:

it("should call parent fetch with default options", function() {
  spyOn(Math, 'random').and.returnValue(0.1);
  this.collection.fetch();
  expect(this.fetchSpy).toHaveBeenCalledWith({
    data: {
      id: 1,
      random: Math.floor(Math.random()*10000)
    }
  }); 
});

Jasmine 1:

it("should call parent fetch with default options", function() {
  jasmine.spyOn(Math, 'random').andReturn(0.1);
  this.collection.fetch();
  expect(this.fetchSpy).toHaveBeenCalledWith({
    data: {
      id: 1,
      random: Math.floor(Math.random()*10000)
    }
  }); 
});

You SHOULD NOT spyOn Math.random.

There are many package using this function (even Jasmine), the better way will be writing a method to wrap the random stuff.

class Fetcher {
  fetch(url) {
    const rand = this.generateRandomNumber(64);
    // ...
  }

  generateRandomNumber(n) {
    return Math.floor(Math.random() * n);
  }
}

Now you can mock it!

it('should pass', () => {
  const fetcher = new Fetcher();
  // mock
  spyOn(fetcher, 'generateRandomNumber').and.returnValues(1,2,3);

  // action
  const result = fetcher.fetch('some-url');

  // assertion
  expect(result).toBe('some-result');
});

If you want to simulate a series of "random" values, you can use:

spyOn(Math, 'random').and.returnValues(0.1, 0.2, 0.3, 0.4);

note that you must add the s in returnValues or it won't work

本文标签: javascriptJasmine specs generating different random numbers than on executionStack Overflow