【问题标题】:Jasmine specs generating different random numbers than on executionJasmine 规范生成的随机数与执行时不同
【发布时间】:2013-04-01 22:34:45
【问题描述】:

我有一个 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) 
    }
  }); 
});

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

【问题讨论】:

    标签: javascript ruby-on-rails testing tdd jasmine


    【解决方案1】:

    您可以模拟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)
        }
      }); 
    });
    

    【讨论】:

      【解决方案2】:

      你不应该 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');
      });
      

      【讨论】:

        【解决方案3】:

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

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

        注意必须在 returnValues 中添加 s 否则不起作用

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-24
          • 2021-12-31
          • 1970-01-01
          相关资源
          最近更新 更多