5

我有一个 Jasmine 测试失败,因为正在生成一个随机数,并且这个随机值对于执行和规范是不同的。

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);
}

下面的测试失败,因为Math.floor(Math.random()*10000)正在生成不同的值。

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) 
    }
  }); 
});

对于生成随机数的情况,有没有办法让我的测试通过?

4

3 回答 3

8

您可以模拟Math.random功能。茉莉花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)
    }
  }); 
});

茉莉花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)
    }
  }); 
});
于 2013-04-01T22:44:26.413 回答
1

你不应该spyOn Math.random

有很多包使用这个功能(甚至Jasmine),更好的方法是编写一个方法来包装随机的东西。

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

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

现在你可以嘲笑它了!

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');
});
于 2021-06-23T07:32:58.803 回答
0

如果要模拟一系列“随机”值,可以使用:

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

请注意,您必须在 returnValue 中添加s否则它将不起作用

于 2017-02-28T10:30:01.707 回答