7

我有以下代码:

class Clients
  constructor : ->
    @clients = []

  createClient : (name)->

    client = new Client name
    @clients.push client

我正在使用 Jasmine BDD 进行测试,如下所示:

describe 'Test Constructor', ->

  it 'should create a client with the name foo', ->

    clients = new clients
    clients.createClient 'Foo'
    Client.should_have_been_called_with 'Foo'

  it 'should add Foo to clients', ->

    clients = new clients
    clients.createClient 'Foo'

    expect(clients.clients[0]).toEqual SomeStub

在我的第一个测试中,我想检查是否使用正确的名称调用了构造函数。在我的第二个中,我只想确认来自新客户端的任何内容都已添加到数组中。

我正在使用 Jasmine BDD,它有一种创建间谍/模拟/存根的方法,但似乎无法测试构造函数。所以我正在寻找一种方法来测试构造函数,如果有一种方法我不需要额外的库但我对任何事情都持开放态度,那就太好了。

4

4 回答 4

9

可以在 Jasmine存根构造函数,语法有点出乎意料:

spy = spyOn(window, 'Clients');

换句话说,您不存根new方法,而是在它所在的上下文中存根类名本身,在这种情况下window。然后,您可以链接 aandReturn()以返回您选择的假对象,或 aandCallThrough()调用真正的构造函数。

另请参阅:使用 Jasmine 监视构造函数

于 2012-07-08T23:44:17.247 回答
4

我认为这里最好的计划是将新对象的创建拉到Client一个单独的方法中。这将允许您单独测试Clients该类并使用模拟Client对象。

我已经编写了一些示例代码,但我还没有使用 Jasmine 对其进行测试。希望您能了解它的工作原理:

class Clients
  constructor: (@clientFactory) ->
    @clients = []

  createClient : (name)->
    @clients.push @clientFactory.create name

clientFactory = (name) -> new Client name

describe 'Test Constructor', ->

  it 'should create a client with the name foo', ->
    mockClientFactory = (name) ->
    clients = new Clients mockClientFactory

    clients.createClient 'Foo'

    mockClientFactory.should_have_been_called_with 'Foo'

  it 'should add Foo to clients', ->
    someStub = {}
    mockClientFactory = (name) -> someStub
    clients = new Clients mockClientFactory

    clients.createClient 'Foo'

    expect(clients.clients[0]).toEqual someStub

基本计划是现在使用单独的函数 ( clientFactory) 来创建新Client对象。然后在测试中模拟这个工厂,允许您准确控制返回的内容,并检查它是否被正确调用。

于 2011-09-29T09:22:34.647 回答
0

我的解决方案最终类似于@zpatokal

我最终在我的应用程序(不是真正的大应用程序)中使用了一个模块,并从那里进行了模拟。一个问题是这and.callThrough不起作用,因为将从 Jasmine 方法调用构造函数,所以我不得不对and.callFake.

在单位.coffee

class PS.Unit

在units.coffee

class PS.Units
  constructor: ->
    new PS.Unit

在规范文件上:

Unit = PS.Unit

describe 'Units', ->
  it 'should create a Unit', ->
    spyOn(PS, 'Unit').and.callFake -> new Unit arguments... # and.callThrough()
    expect(PS.Unit).toHaveBeenCalled()
于 2014-12-03T01:49:52.717 回答
0

最近的茉莉花版本更清晰的解决方案:

window.Client = jasmine.createSpy 'Client'
clients.createClient 'Foo'
expect(window.Client).toHaveBeenCalledWith 'Foo'
于 2015-09-16T04:47:40.293 回答