【问题标题】:jasmin: mock instance of a classjasmin:类的模拟实例
【发布时间】:2014-03-26 07:55:55
【问题描述】:

是否可以创建一个对象 obj 的模拟,这样 Jasmine 测试就像

expect(fakeB instanceof B).toBe(true);

通过?

换句话说,我有一个类 A 有一个方法 convertToB,它的参数必须是类 B 的一个实例: p>

function A(){
  this.convertToB = function(elem){
    if (!(elem instanceof B)){ throw an error}
    ...
    ... 
  }
}

我想通过创建一个模拟对象来测试那段代码,当被问及它是否是 B 的实例时,它会响应 true

目前我不得不写一些测试

  1. it('如果参数是字符串则抛出错误')
  2. it('如果参数是数组则抛出错误')
  3. ...

这有点烦人。我期望像

这样的命令
 var fakeB = jasmine.createFake('B')

这样这个问题的第一行代码就会通过。

【问题讨论】:

    标签: javascript tdd jasmine


    【解决方案1】:

    我的代码中有几十个地方和你的完全一样。 Jasmine 2.0 的 spyOn 方法将完成这项工作。与 Jasmine 1.0 相同,但我不记得该方法是否以完全相同的方式调用/使用。举个例子:

    var realB = new B();
    
    // change realB instance into a spy and mock its method 'foo' behaviour to always return 'bar'
    // it will still respond "true" to "realB instanceof B"
    spyOn(realB, 'foo').and.returnValue('bar')
    
    var realC = new C();
    
    // C.baz is expecting instance of B to be passed as first argument
    var result = C.baz(realB)
    
    // assuming C.baz return realB.foo() concatenated with '123'
    expect(result).toEqual('bar123');
    

    Jasmine 文档包含大量间谍示例:http://jasmine.github.io/2.0/introduction.html

    【讨论】:

    • 感谢您的回复!换句话说,你说的是,如果我创建一个通过 new B() 初始化的变量 realB,这个变量将是 B。无论如何,是否会模拟 realB 的方法。这没关系。但是通过这种方式, if (!(elem instanceof B)){ throw an error} 行仍然未被覆盖,并且为了用测试覆盖它,我将不得不创建一堆不是实例的对象B 并将它们传递给 convertB 方法。
    • 是的,模拟方法不会改变类型。要涵盖抛出错误,您必须编写另一个测试并在测试传递非 B 类型的参数下调用方法。例如数字或对象文字。
    【解决方案2】:

    我的实现如下:

    function proxyConstructor(obj) {
      obj = obj || {};
      for (var key in obj) {
        this[key] = obj[key];
      }
    
      this.prop = 'runtime prop';
      this.instanceMethod(1);
    }
    
    var TestClass = jasmine.createSpy(`TestClass.constructor`).and.callFake(proxyConstructor);
    TestClass.prototype.instanceMethod = jasmine.createSpy(`TestClass#instanceMethod`);
    TestClass.staticMethod = jasmine.createSpy(`TestClass.staticMethod`);
    
    var ins = new TestClass();
    expect(ins).toBe(jasmine.any(TestClass)) // success
    expect(ins.prop).toBe('runtime prop'); // success
    expect(ins.instanceMethod.toHaveBeenCalledWith(1)) // success

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2013-07-17
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多