brenolf/factory-granny

语言: JavaScript

git: https://github.com/brenolf/factory-granny

用于构建灵活JavaScript对象的工厂。灵感来自factory_girl。
Factory for building flexible JavaScript objects. Inspired by factory_girl.
README.md (中文)





Build Status
Coverage Status
Code Climate
npm version

Pocahontas,你在期待谁?

Factory Granny是Factories的JavaScript库,它与其他库不同,因为它还允许您构建函数而不是对象;这个小功能允许您直接使用Factory实例而不需要存根许多功能,从而简化了测试开发。

安装

$ npm install --save-dev factory-granny

用法

静态方法

var Factory = require('factory-granny')

var sinon = require('sinon')

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', sinon.stub)

var instance = Factory('User').get()

在此示例中,实例是一个在使用new调用时始终返回对象{username:'brenolf'}的函数。此外,此函数将具有作为存根的sayMyName属性。就如此容易!

静态属性也可能与其他字段有依赖关系:

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', ['name'], function (name) {
    return 'Hello ' + name
})

最终,您可以跟踪每次调用时返回的实例的更改,从而监视它们。

// user-factory.js
module.exports = Factory('User')
.attr('name', 'brenolf')
.attr('spy', sinon.stub)
.static('sayMyName', ['name'], function (name) {
    return 'Hello ' + name
})

// test.js
var UserFactory = require('user-factory.js')

var user = UserFactory.get()
var instance = user._instance

// ...

expect(instance.spy).to.have.been.calledOnce

您也可以调用build而不是get来获取具有给定的所有属性的对象,但不需要实例化返回的函数。

var UserFactory = require('user-factory.js')

/*
    user_fn = function () {
        return {
            name: 'brenolf',
            spy: sinon.stub()
        }
    }
*/
var user_fn = UserFactory.get()

/*
    user = {
        name: 'brenolf',
        spy: sinon.stub()
    }
*/
var user = UserFactory.build()

性状

Factory Granny使您在开发过程中使用特性变得非常容易。

Factory('User.ABQ')
.attr('name', 'heisenberg')

Factory('User.ABQ').get().sayMyName

事实上,您不需要先写父工厂。您可以通过调用propagate来首先定义特征,然后再定义其父元素。

Factory('Name.trait')
.attr('name', 'This is my name')

Factory('Name')
.attr('name', 'Main name')
.attr('parent', true)
.propagate()

Factory('Name').build() // { name: 'Main name', parent: true }

Factory('Name.trait').build() // { name: 'This is my name', parent: true }

如果你没有在父链的末尾调用传播,那么它的所有特征都不会继承它的属性。

工厂包装盒

Factory Granny附带了一些存根,可以让您更快地为工厂写作。例如:

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', Factory.box.true())
.static('find', Factory.box.chain('User.ABQ'))

还有许多其他别名可以让你为工厂写一个有趣的工作:

Method Equivalent
simple() sinon.stub()
true() sinon.stub().returns(true)
false() sinon.stub().returns(false)
returns(value) sinon.stub().returns(value)
throws() sinon.stub().throws()
resolves(value) A sinon promise stub which resolves to a given value ({} if none given)
rejects() A sinon promise stub that rejects
build(Factory) Returns an instance of the class provided (last factory created if none given)
chain(Factory) A sinon stub that returns a .build() of the given factory (last factory created if none given)
chainAsync(Factory) A sinon stub that resolves a .build() of the given factory (last factory created if none given)

接收工厂字符串作为参数的函数都是延迟加载的。因此,您可以使用尚未创建但在以后调用构建时可用的工厂。

使用Factory.box的最大好处是与工厂合作。由于每个函数都在每个构建和get调用上进行求值,如果你想要一个属性求值为函数值(例如使用sinon stubs),你需要写下一个返回函数指针的函数。工厂奶奶为你做了这件事!

请注意,Factory Granny使用sinon作为其存根。

基本用法

Factory Granny以Rosie为基础。 Rosie的任何有效编队也适用于Factory Granny。

执照

Apache许可证

本文使用googletrans自动翻译,仅供参考, 原文来自github.com

en_README.md





Build Status
Coverage Status
Code Climate
npm version

Who were you expecting, Pocahontas?

Factory Granny is a JavaScript library for Factories that is different from the others because it also allows you to build functions instead of objects; This little feature eases test development by allowing you to directly use a Factory instance instead of needing to stub many functions.

Install

$ npm install --save-dev factory-granny

Usage

Static methods

var Factory = require('factory-granny')

var sinon = require('sinon')

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', sinon.stub)

var instance = Factory('User').get()

In this example instance is a function that always returns an object {username: 'brenolf'} when called with new. Also, this function will have a sayMyName property that is a stub. As simple as that!

Static attributes may also have dependencies over other fields:

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', ['name'], function (name) {
    return 'Hello ' + name
})

Ultimately you can track the changes of the instance being returned on every get called, and thus, spy on them.

// user-factory.js
module.exports = Factory('User')
.attr('name', 'brenolf')
.attr('spy', sinon.stub)
.static('sayMyName', ['name'], function (name) {
    return 'Hello ' + name
})

// test.js
var UserFactory = require('user-factory.js')

var user = UserFactory.get()
var instance = user._instance

// ...

expect(instance.spy).to.have.been.calledOnce

You can also call build instead of get in order to get an object with all the attributes given, but not needing to instantiate the returned function.

var UserFactory = require('user-factory.js')

/*
    user_fn = function () {
        return {
            name: 'brenolf',
            spy: sinon.stub()
        }
    }
*/
var user_fn = UserFactory.get()

/*
    user = {
        name: 'brenolf',
        spy: sinon.stub()
    }
*/
var user = UserFactory.build()

Traits

Factory Granny makes it super easy to use traits in your development.

Factory('User.ABQ')
.attr('name', 'heisenberg')

Factory('User.ABQ').get().sayMyName

As a matter of fact, you don't need to first write the parent factory. You can define a trait first and later its parent just by calling propagate.

Factory('Name.trait')
.attr('name', 'This is my name')

Factory('Name')
.attr('name', 'Main name')
.attr('parent', true)
.propagate()

Factory('Name').build() // { name: 'Main name', parent: true }

Factory('Name.trait').build() // { name: 'This is my name', parent: true }

If you don't call propagate at the end of the parents' chain, then all of its traits will not inherit its attributes.

Factory box

Factory Granny comes with a handful of stubs to make writing you factories even faster. For example:

Factory('User')
.attr('name', 'brenolf')
.static('sayMyName', Factory.box.true())
.static('find', Factory.box.chain('User.ABQ'))

There are many other aliases to make writing you factories a fun work:

Method Equivalent
simple() sinon.stub()
true() sinon.stub().returns(true)
false() sinon.stub().returns(false)
returns(value) sinon.stub().returns(value)
throws() sinon.stub().throws()
resolves(value) A sinon promise stub which resolves to a given value ({} if none given)
rejects() A sinon promise stub that rejects
build(Factory) Returns an instance of the class provided (last factory created if none given)
chain(Factory) A sinon stub that returns a .build() of the given factory (last factory created if none given)
chainAsync(Factory) A sinon stub that resolves a .build() of the given factory (last factory created if none given)

The functions that receives a factory string as parameter are all lazy loaded. Therefore, you can use factories that are not created yet but will be available when build is later called.

The greatest advantage of using Factory.box is when working with the factories. Since every function is evaluated on each build and get calls, if you wanted to have an attribute evaluated to a function value (using sinon stubs, for instance) you would need to write down a function that returns a function pointer. Factory Granny does that for you under the hood!

Note that Factory Granny is opinionated using sinon for its stubs.

Basic Usage

Factory Granny uses Rosie as its basis. Any valid formation for Rosie is also valid for Factory Granny.

License

Apache License