Javascript 模拟/存根构造函数
我有以下代码:Javascript 模拟/存根构造函数,javascript,coffeescript,jasmine,Javascript,Coffeescript,Jasmine,我有以下代码: 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 nam
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,它有一种创建间谍/模拟/存根的方法,但似乎不可能测试构造函数。因此,我正在寻找一种方法来测试构造函数。如果有一种方法我不需要额外的库,但我对任何事情都持开放态度,那就太好了。我认为最好的计划是将新
客户机
对象的创建拉到一个单独的方法中。这将允许您单独测试客户机
类,并使用mock客户机
对象
我已经编写了一些示例代码,但还没有用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
对象。然后在测试中模拟此工厂,允许您精确控制返回的内容,并检查它是否被正确调用。它可以在Jasmine中删除构造函数,语法有点出乎意料:
spy = spyOn(window, 'Clients');
换句话说,您不需要将new
方法存根,而是将类名本身存根在它所在的上下文中,在本例中是窗口
。然后,您可以链接一个andReturn()
来返回您选择的假对象,或者链接一个andCallThrough()
来调用真正的构造函数
另请参见:我的解决方案与@zpatokal类似 最后,我在我的应用程序(不是真正的大应用程序)上使用了一个模块,并在那里进行了模拟。一个问题是
和.callThrough
将不起作用,因为构造函数将从Jasmine方法调用,所以我不得不对和.callFake
进行一些技巧
咖啡
class PS.Unit
咖啡
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()
最新茉莉花版本的更清晰解决方案:
window.Client = jasmine.createSpy 'Client'
clients.createClient 'Foo'
expect(window.Client).toHaveBeenCalledWith 'Foo'
我担心我必须用这种方法来解决它。尽管如此,还是很好的回答,谢谢。如果客户端是闭包上的变量,那么这就不起作用了。