如何覆盖jasmine的buildExpectationResult以修改message()函数?

时间:2015-11-11 14:48:04

标签: jasmine protractor

我使用量角器进行e2e测试,使用jasmine2作为框架。我正在使用html报告器的插件和截图(html-report for protractor)。

在这些报告中,将显示所有失败/通过的期望的列表。当期望失败时,我会收到期望的描述性消息。但是,当期望通过时,我只会看到单词:已通过。背后的原因是,当期望通过时,jasmine会覆盖该消息。< / p>

在以下文件中完成:

 node_modules/protractor/node_modules/jasmine/node_modules/jasmine-core/lib/jasmine-core/jasmine.js
getJasmineRequireObj().buildExpectationResult = function () {
    function buildExpectationResult(options) {
        var messageFormatter = options.messageFormatter || function () {
                },
            stackFormatter = options.stackFormatter || function () {
                };

        var result = {
            matcherName: options.matcherName,
            message: message(),
            stack: stack(),
            passed: options.passed
        };

        if (!result.passed) {
            result.expected = options.expected;
            result.actual = options.actual;
        }

        return result;

        function message() {
            if (options.passed) {
                // Here is the message overriden
                return 'Passed.';
            } else if (options.message) {
                return options.message;
            } else if (options.error) {
                return messageFormatter(options.error);
            }
            return '';
        }

        function stack() {
            if (options.passed) {
                return '';
            }

            var error = options.error;
            if (!error) {
                try {
                    throw new Error(message());
                } catch (e) {
                    error = e;
                }
            }
            return stackFormatter(error);
        }
    }

    return buildExpectationResult;
};

我想要的是在我的量角器 protractor.conf.js 文件中覆盖此功能。并将其替换为具有所需行为的一个。

我尝试这样做但未成功执行以下操作:

onPrepare: function () {
    jasmine.buildExpectationResult = function () {
        function buildExpectationResult(options) {
            var messageFormatter = options.messageFormatter || function () {
                    },
                stackFormatter = options.stackFormatter || function () {
                    };

            return {
                matcherName: options.matcherName,
                expected: options.expected,
                actual: options.actual,
                message: message(),
                stack: stack(),
                passed: options.passed
            };

            function message() {
                if (options.message) {
                    return options.message;
                } else if (options.error) {
                    return messageFormatter(options.error);
                }
                return "";
            }

            function stack() {
                if (options.passed) {
                    return "";
                }

                var error = options.error;
                if (!error) {
                    try {
                        throw new Error(message());
                    } catch (e) {
                        error = e;
                    }
                }
                return stackFormatter(error);
            }
        }

        return buildExpectationResult;
    };
} 

然后我的问题是:覆盖茉莉花方法的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

由于我们使用gulp任务来运行量角器测试,我们将lib(如jasmine lib)覆盖为自定义副本的gulp任务之一。我们这样做是安装或每次测试执行的一部分。

除非我们创建另一个npm模块,否则我找不到覆盖它的好方法。

答案 1 :(得分:0)

我遇到了同样的问题,我不确定我的解决方案

onPrepare: function () {
// ...
jasmine.Spec.prototype.addExpectationResult = function(passed, data, isError) {
  var buildExpectationResult = function(options) {
      var messageFormatter = options.messageFormatter || function() {},
        stackFormatter = options.stackFormatter || function() {};
  
      var result = {
        matcherName: options.matcherName,
        message: message(),
        stack: stack(),
        passed: options.passed
      };
  
      if(!result.passed) {
        result.expected = options.expected;
        result.actual = options.actual;
      }
  
      return result;
  
      function message() {
        if (options.passed) {
          return options.message ? options.message : 'Passed';
        } else if (options.message) {
          return options.message;
        } else if (options.error) {
          return messageFormatter(options.error);
        }
        return '';
      }
  
      function stack() {
        if (options.passed) {
          return '';
        }
  
        var error = options.error;
        if (!error) {
          try {
            throw new Error(message());
          } catch (e) {
            error = e;
          }
        }
        return stackFormatter(error);
      }
    }

  var exceptionFormatter = jasmine.ExceptionFormatter;

  var expectationResultFactory = function(attrs) {
    attrs.messageFormatter = exceptionFormatter.message;
    attrs.stackFormatter = exceptionFormatter.stack;

    return buildExpectationResult(attrs);
  }

  var expectationResult = expectationResultFactory(data);

  if (passed) {
    this.result.passedExpectations.push(expectationResult);
  } else {
    this.result.failedExpectations.push(expectationResult);

    if (this.throwOnExpectationFailure && !isError) {
      throw new j$.errors.ExpectationFailed();
    }
  }
};

// ...
}