gpt4 book ai didi

javascript - 使用 javascript/coffeescript 的依赖注入(inject)以帮助可测试性

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:03:08 27 4
gpt4 key购买 nike

我正在使用 Jasmine 进行一些测试在我的网络应用程序中。我正在使用 Coffeescript编写我的模型、服务和 View 模型。

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

@service = new MyService
alertId: @alert.elementId

现在我用 Jasmine 写一个测试

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()

所以这里的问题是我在我的 viewModel 中依赖于 alertservice。这使得编写和维护测试变得很烦人。

Javascript 中是否有用于依赖注入(inject)的库。我用过几个 .net 库,比如 castle windsorninject

或者我应该只采用某种类型模式。我应该说我正在使用 knockout当我在我的实际应用程序中使用 View 模型时,它看起来像这样。

<script type="text/javascript">

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

</script>

我假设不是创建自己的对象,而是向注入(inject)框架询问 MyViewModel 的实例。

我正在寻找关于采用什么模式或库的建议,以使我的测试更容易一些,并帮助将我的 javascript 类彼此解耦。


我找到的库:

  • Wire - 只有 ECMA 5+,我需要支持旧版浏览器
  • Dijon - 看起来不错,但我还没有尝试过。

编辑:我最终做了什么

  • 我采用了 RequireJs 并将我所有的对象移动到 AMD 风格的模块中
  • 我使用 Jamine 来运行测试
  • 我使用 Sinon 创建模拟和 stub
  • 我使用 Squire 将模拟和 stub 注入(inject)到我的测试系统中

查看测试文件的 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)

最佳答案

有一个库为 Coffeescript 提供与 ninject 非常相似的功能,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

然后,您的测试将像使用 ninjectGuice 或类似工具一样工作。您在模块/绑定(bind)器中描述您的测试对象,并在测试时简单地为您的类请求注入(inject)器。

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()

关于javascript - 使用 javascript/coffeescript 的依赖注入(inject)以帮助可测试性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16796502/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com