2011-09-25 9 views
7

tengo el siguiente código:Mock/stub constructor

class Clients 
    constructor : -> 
    @clients = [] 

    createClient : (name)-> 

    client = new Client name 
    @clients.push client 

estoy probando con Jasmine BDD así:

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 

En mi primera prueba que quiero comprobar si el constructor está siendo llamado con el nombre correcto. En mi segundo solo quiero confirmar que todo lo que salió del nuevo cliente se agregó a la matriz.

Estoy usando Jasmine BDD y tiene una forma de crear espías/burlas/stubs pero parece que no es posible probar el constructor. Así que estoy buscando una manera de probar el constructor, sería bueno si hubiera una manera en que no necesite una biblioteca adicional, pero estoy abierto a todo.

Respuesta

4

Creo que el mejor plan aquí es sacar la creación del nuevo objeto Client a un método diferente. Esto le permitirá probar la clase Clients aisladamente y usar objetos simulados Client.

He creado un código de ejemplo, pero no lo he probado con Jasmine. Esperemos que se puede obtener la esencia de cómo funciona:

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 

El plan básico es utilizar ahora una función separada (clientFactory) para crear nuevos objetos Client. Luego, se burla de esta fábrica en las pruebas, lo que le permite controlar exactamente lo que se devuelve e inspeccionar que se haya llamado correctamente.

+0

Tenía miedo de tener que resolverlo de esta manera. No obstante gran respuesta gracias. – Pickels

9

Se es posible apagar los constructores de jazmín, la sintaxis es un poco inesperado:

spy = spyOn(window, 'Clients'); 

En otras palabras, no se tropieza a cabo el método new, usted tropieza a cabo la clase nombre en el contexto donde vive, en este caso window. A continuación, puede encadenar en un andReturn() para devolver un objeto falso de su elección, o un andCallThrough() para llamar al constructor real.

Consulte también: Spying on a constructor using Jasmine

+1

Esto realmente no funciona si los Clientes son una variable en un cierre. – Zequez

0

Mi solución terminó similar a @zpatokal

Terminé usando un módulo al otro lado de mi aplicación (no muy grande aplicación), y burlándose de allí. Una pega es que and.callThrough no funcionará, ya que el constructor va a ser llamado desde el método Jasmine, así que tuve que hacer algún truco con and.callFake.

En unit.coffee

class PS.Unit 

En units.coffee

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

Y en los archivos de especificaciones:

Unit = PS.Unit 

describe 'Units', -> 
    it 'should create a Unit', -> 
    spyOn(PS, 'Unit').and.callFake -> new Unit arguments... # and.callThrough() 
    expect(PS.Unit).toHaveBeenCalled() 
0

solución más clara con la versión reciente de jazmín:

window.Client = jasmine.createSpy 'Client' 
clients.createClient 'Foo' 
expect(window.Client).toHaveBeenCalledWith 'Foo' 
Cuestiones relacionadas