4

Я тестирую с Jasmine в своем веб-приложении. Я использую Coffeescript, чтобы написать свои модели, услуги и просмотреть модели.Зависимость впрыска с javascript/coffeescript, чтобы помочь тестированию

class MyViewModel 
    constructor: (@options) -> 
    @alert = new Alert 
     elementId: 'my-alert-element-id' 

    @service = new MyService 
     alertId: @alert.elementId 

Теперь я пишу тест в жасмин

describe 'MyViewModel', -> 
    sut = null 

    beforeEach -> 
    sut = new MyViewModel() 

    afterEach -> 
    sut = null 

    describe 'constructor()', -> 
    it 'creates a new instance of the ViewModel', -> 
     expect(sut).not.toBeNull() 

Таким образом, проблема здесь в том, что у меня есть зависимость от alert и service в моем viewModel. Это заставляет тесты раздражать писать и поддерживать.

Существуют ли библиотеки для инъекций в JavaScript в Javascript. Я использовал несколько библиотек .net, таких как castle windsor и ninject.

Или я должен просто принять шаблон определенного типа. Я должен сказать, что я использую knockout, и когда я использую viewmodel в своем фактическом приложении, он выглядит примерно так.

<script type="text/javascript"> 

    $(function() { 
    var viewModel = new MyViewModel(); 
    ko.applyBindings(viewModel); 
    }); 

</script> 

Вместо того, чтобы мне создать свой собственный объект, я бы просить рамки инъекции для экземпляра MyViewModel я полагаю.

Я ищу совет относительно того, какой шаблон или библиотека принять, чтобы сделать мое тестирование немного проще и помочь развязать мои классы javascript друг от друга.


Libs Я нашел:

  • Wire - Только ECMA 5+ и мне нужно поддерживать старые браузеры
  • Dijon - Выглядит хорошо, но я не пробовал еще.

EDIT: То, что я в конечном итоге делает

  • Я принял RequireJs и переместил все свои объекты в модули типа AMD
  • Я использую Jamine для запуска тестов
  • я использую Sinon для создания фальшивок и заглушек
  • Я использую Squire для впрыскивания макетов и заглушек в мою тестируемую систему

См CoffeeScript пример тестового файла

define ['squire', 'sinon' ], (squire, sinon) -> 
    describe '==== a view model ====', -> 
    sut = null 
    testContext = null 

    beforeEach -> 
     testContext = 
     squireInjector: new squire 
     stubService: sinon.stub() 
     stubJquery: sinon.stub() 
     someCallbackSpy: sinon.spy() 

     testContext.squireInjector.mock( 
     'jquery', squire.Helpers.returns(stubJquery)) 

     testContext.squireInjector.require ['aViewModel'], (viewModel) => 
     sut = new viewModel 
      service: testContext.stubService 
      someCallback: testContext.someCallbackSpy 

     waitsFor(-> sut?) 

    afterEach -> 
     sut = null 
     testContext = null 

    describe 'the constructor method should', -> 
     it 'create a new instance of the view 
     model and have required dependencies', -> 
     expect(sut).toBeDefined 
     expect(sut.service).toBeDefined 
     expect(sut.someCallback).toBeDefined 

    describe 'the next method should', -> 
     it 'increment the route id by one', -> 
     # Arrange 
     sut.routeId = 5 

     # Act 
     sut.next() 

     # Assert 
     expect(sut.routeId).toEqual(6) 
     expect(testContext.someCallbackSpy.called).toBe(true) 
+0

Отличный напишите! Спасибо – gumaflux

+0

Жасмин также поддерживает создание mocks и stubs. Любая конкретная причина для Синона? –

ответ

1

Вы можете использовать requirejs, и один из этих решений:

Или вы просто издеваетесь над прототипами ваших объектов.

jasmine.spy(Alert.prototype, 'someFunction') 

КПП. вы можете использовать wire.js со старым браузером, используя прокладку. Из документов:

Для поддержки не-ES5 устаревших браузеров, wire.js 0.9.x требует поли 0.5.0 или выше. Вы можете клонировать или загрузить поли в свой проект, или установить его через YEOMAN/беседке:

+0

Будет ли переходить к требованию полной перезаписи всех моих js для работы в их рамках? – Neil

+0

Это было бы в случае с любым решением, но поскольку вы используете классы coffeescript, которые могут быть просто преобразованы в модуль requirejs, это не должно быть так много. –

+0

Спасибо, очень ценится. – Neil

2

Существует библиотека, которая обеспечивает очень схожую функциональность ninject для CoffeeScript, honk-di. Here's a helpful write up об этом. Ваш пример станет чем-то больше, как это:

class MyViewModel 
    elementId: inject('element.id') # Inject a constant 
    alert:  inject(Alert) 
    service: inject(MyService) 

    constructor: -> 
    @alert.elementId = @elementId 
    @service.alertId = @alert.elementId 

Тогда ваши тесты будут работать так же, как они будут с ninject, Guice, или аналогичный. Вы описываете свои объекты тестирования в модуле/связующем и просто спрашиваете инжектор для своего класса во время тестирования.

describe 'MyViewModel', -> 
    sut = null 

    beforeEach -> 
    # Assuming you've made mocks or simplified classes for 
    # Alert and MyService which are set up in TestModule. 
    # `element.id` will also need a definition. 
    injector = new inject.Injector(new TestModule()) 
    sut = injector.getInstance(MyViewModel) 

    afterEach -> 
    sut = null 

    describe 'constructor()', -> 
    it 'creates a new instance of the ViewModel', -> 
     expect(sut).not.toBeNull() 

 Смежные вопросы

  • Нет связанных вопросов^_^