柴如何期待功能的运作?

时间:2015-07-24 08:12:52

标签: javascript mocha chai

从chai的api你有这样的代码:

-(void)setCopyedString:(NSMutableString *)copyedString{
    _copyedString = [copyedString mutableCopy];
}

这是如何存在部分工作的? expect函数返回一个对象,然后在"到"上只需要一个属性查找。宾语。这只是一项财产评估,但不是吗?对我来说唯一有意义的是,如果存在属性是一个getter方法。

该怎么回事?

2 个答案:

答案 0 :(得分:3)

chai公开use方法来访问chai导出,并utils

creating plugins时,第三方可以使用此方法,但内部也可以使用此方法加载其接口。

这种方法的实现很简单:

exports.use = function (fn) {
  if (!~used.indexOf(fn)) {
    fn(this, util);
    used.push(fn);
  }

  return this;
};

在内部,它使用它来加载(以及其他)主要Assertion prototype和核心断言功能:

var assertion = require('./chai/assertion'); // primary Assertion prototype
exports.use(assertion); // load it

var core = require('./chai/core/assertions'); // core assertion functionality
exports.use(core); // load it

Assertion prototype公开的方法之一是addProperty方法,它允许您向所述prototype添加属性。

内部chai使用此方法将核心断言功能添加到Assertion prototype。例如,所有语言链和断言助手(existempty等)都以这种方式添加。

语言链:

[ 'to', 'be', 'been'
  , 'is', 'and', 'has', 'have'
  , 'with', 'that', 'which', 'at'
  , 'of', 'same' ].forEach(function (chain) {
    Assertion.addProperty(chain, function () {
      return this;
    });
  });

当内部加载特定接口时,所有这些功能都可用,例如expect。加载此接口后,只要执行Assertion prototype,就会实例化一个新的expect,其中包含所有功能:

// load expect interface
var expect = require('./chai/interface/expect'); // expect interface
exports.use(expect); // load it

// expect interface
module.exports = function (chai, util) {
  chai.expect = function (val, message) {
    return new chai.Assertion(val, message); // return new Assertion Object with all functionality
  };
};

如您所见,expect方法接受val参数(以及可选的message参数)。调用此方法时(例如expect(foo))将实例化并返回新的Assertion prototype,从而暴露所有核心功能(允许您执行expect(foo).to.exist)。

Assertion Constructor使用flag util在Object上设置一个标记值,该值映射到传入的val参数。

  function Assertion (obj, msg, stack) {
    flag(this, 'ssfi', stack || arguments.callee);
    flag(this, 'object', obj); // the 'object' flag maps to the passed in val
    flag(this, 'message', msg);
  }

然后,所有exist都通过flag util获取此值,并使用定义的null方法评估它是否等于assertAssertion prototype

  Assertion.addProperty('exist', function () {
    this.assert(
        null != flag(this, 'object')
      , 'expected #{this} to exist'
      , 'expected #{this} to not exist'
    );
  });

答案 1 :(得分:1)

当你调用expect(foo)时,会实例化一个新的Assertion对象。

to,have,with和类似属性除了返回Assertion实例之外什么都不做。它们只是为了便于阅读。

但是,在您的示例中,存在,实际上是运行断言的东西。

它的财产。他们将属性添加到Assertion的方式是将它们定义为getter函数see here.

expect(foo).to.exist可以分解为:

const assertion = new Assertion;
assertion.exists;
使用getter将

assertion.exists添加到断言对象。 这意味着当您执行assertion.exists以评估assertion.exists的值时,会执行先前提供给addProperty的函数。

您可以阅读有关getter functions的更多信息。