我正在我的网络应用中使用Jasmine
实施一些测试。我正在使用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中是否存在用于依赖注入的库。我使用了castle windsor
和.net
等多个ninject
库。
或者我应该采用某种类型的模式。我应该说我正在使用knockout
,当我在实际应用程序中使用viewmodel时,它看起来像这样。
<script type="text/javascript">
$(function () {
var viewModel = new MyViewModel();
ko.applyBindings(viewModel);
});
</script>
而不是我创建自己的对象,我会问我假设的MyViewModel
实例的注入框架。
我正在寻找有关采用什么模式或库的建议,以使我的测试更容易一些,并帮助将我的javascript类彼此分离。
Libs我发现:
编辑:我最终做了什么
请参阅测试文件的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 :(得分:2)
有一个库为Coffeescript honk-di提供与ninject
非常相似的功能。 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()
答案 1 :(得分:1)
您可以使用requirejs,以及其中一个解决方案:
或者您只是嘲笑对象的原型。
jasmine.spy(Alert.prototype, 'someFunction')
顺便说一下。您可以使用垫片将wire.js与旧浏览器一起使用。来自文档:
要支持非ES5旧版浏览器,wire.js 0.9.x需要poly 0.5.0 或更高。您可以克隆或下载poly到您的项目中,或 通过yeoman / bower安装它: