Конструктор Mock / Stub - PullRequest
       8

Конструктор Mock / Stub

7 голосов
/ 26 сентября 2011

У меня есть следующий код:

class Clients
  constructor : ->
    @clients = []

  createClient : (name)->

    client = new Client name
    @clients.push client

Я тестирую его с Жасмин 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 ]

9 голосов
/ 09 июля 2012

Это можно заглушить конструкторы в Jasmine, синтаксис немного неожиданный:

spy = spyOn(window, 'Clients');

Другими словами, вы не заглушаете newметод, вы заглушаете имя класса в контексте, где он живет, в данном случае window.Затем вы можете связать andReturn(), чтобы вернуть поддельный объект по вашему выбору, или andCallThrough(), чтобы вызвать реальный конструктор.

См. Также: Следите за конструктором с помощью Jasmine

4 голосов
/ 29 сентября 2011

Я думаю, что лучший план здесь состоит в том, чтобы вытащить создание нового объекта Client в отдельный метод.Это позволит вам тестировать класс Clients изолированно и использовать фиктивные Client объекты.

Я набрал несколько примеров кода, но не тестировал его с Жасмином.Надеемся, вы сможете понять суть его работы:

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 объектов.Эта фабрика затем проверяется в тестах, позволяя вам точно контролировать, что возвращается, и проверять, правильно ли он был вызван.

0 голосов
/ 16 сентября 2015

Более четкое решение с последней версией жасмина:

window.Client = jasmine.createSpy 'Client'
clients.createClient 'Foo'
expect(window.Client).toHaveBeenCalledWith 'Foo'
0 голосов
/ 03 декабря 2014

Мое решение оказалось похожим на @ zpatokal

Я закончил тем, что использовал модуль через мое приложение (не очень большое приложение) и издевался над этим. Одна загвоздка в том, что and.callThrough не будет работать, так как конструктор будет вызываться из метода Jasmine, поэтому мне пришлось проделать некоторую хитрость с and.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()
...