Path: blob/trunk/third_party/closure/goog/testing/functionmock.js
4503 views
/**1* @license2* Copyright The Closure Library Authors.3* SPDX-License-Identifier: Apache-2.04*/56/**7* @fileoverview Enable mocking of functions not attached to objects8* whether they be global / top-level or anonymous methods / closures.9*10* See the unit tests for usage.11*/1213goog.setTestOnly('goog.testing');14goog.provide('goog.testing');15goog.provide('goog.testing.FunctionMock');16goog.provide('goog.testing.GlobalFunctionMock');17goog.provide('goog.testing.MethodMock');1819goog.require('goog.object');20goog.require('goog.testing.LooseMock');21goog.require('goog.testing.Mock');22goog.require('goog.testing.MockInterface');23goog.require('goog.testing.PropertyReplacer');24goog.require('goog.testing.StrictMock');252627/**28* Class used to mock a function. Useful for mocking closures and anonymous29* callbacks etc. Creates a function object that extends goog.testing.Mock.30* @param {string=} opt_functionName The optional name of the function to mock.31* Set to '[anonymous mocked function]' if not passed in.32* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or33* goog.testing.Mock.STRICT. The default is STRICT.34* @return {!goog.testing.MockInterface} The mocked function.35* @suppress {missingProperties} Mocks do not fit in the type system well.36*/37goog.testing.FunctionMock = function(opt_functionName, opt_strictness) {38'use strict';39var fn = function() {40'use strict';41var args = Array.prototype.slice.call(arguments);42args.splice(0, 0, opt_functionName || '[anonymous mocked function]');43return fn.$mockMethod.apply(fn, args);44};45var base = opt_strictness === goog.testing.Mock.LOOSE ?46goog.testing.LooseMock :47goog.testing.StrictMock;48goog.object.extend(fn, new base({}));4950return /** @type {!goog.testing.MockInterface} */ (fn);51};525354/**55* Mocks an existing function. Creates a goog.testing.FunctionMock56* and registers it in the given scope with the name specified by functionName.57* @param {Object} scope The scope of the method to be mocked out.58* @param {string} functionName The name of the function we're going to mock.59* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or60* goog.testing.Mock.STRICT. The default is STRICT.61* @return {!goog.testing.MockInterface} The mocked method.62* @suppress {strictMissingProperties} $propertyReplacer_ and $tearDown are63* not defined on goog.testing.MockInterface64*/65goog.testing.MethodMock = function(scope, functionName, opt_strictness) {66'use strict';67if (!(functionName in scope)) {68throw new Error(functionName + ' is not a property of the given scope.');69}7071var fn = goog.testing.FunctionMock(functionName, opt_strictness);7273fn.$propertyReplacer_ = new goog.testing.PropertyReplacer();74fn.$propertyReplacer_.set(scope, functionName, fn);75fn.$tearDown = goog.testing.MethodMock.$tearDown;7677return fn;78};798081/**82* @private83* @record @extends {goog.testing.MockInterface}84*/85goog.testing.MethodMock.MockInternalInterface_ = function() {};8687/** @const {!goog.testing.PropertyReplacer} */88goog.testing.MethodMock.MockInternalInterface_.prototype.$propertyReplacer_;899091/**92* Resets the global function that we mocked back to its original state.93* @this {goog.testing.MockInterface}94*/95goog.testing.MethodMock.$tearDown = function() {96'use strict';97/** @type {!goog.testing.MethodMock.MockInternalInterface_} */ (this)98.$propertyReplacer_.reset();99};100101102/**103* Mocks a global / top-level function. Creates a goog.testing.MethodMock104* in the global scope with the name specified by functionName.105* @param {string} functionName The name of the function we're going to mock.106* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or107* goog.testing.Mock.STRICT. The default is STRICT.108* @return {!goog.testing.MockInterface} The mocked global function.109*/110goog.testing.GlobalFunctionMock = function(functionName, opt_strictness) {111'use strict';112return goog.testing.MethodMock(goog.global, functionName, opt_strictness);113};114115116/**117* Convenience method for creating a mock for a function.118* @param {string=} opt_functionName The optional name of the function to mock119* set to '[anonymous mocked function]' if not passed in.120* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or121* goog.testing.Mock.STRICT. The default is STRICT.122* @return {!goog.testing.MockInterface} The mocked function.123*/124goog.testing.createFunctionMock = function(opt_functionName, opt_strictness) {125'use strict';126return goog.testing.FunctionMock(opt_functionName, opt_strictness);127};128129130/**131* Convenience method for creating a mock for a method.132* @param {Object} scope The scope of the method to be mocked out.133* @param {string} functionName The name of the function we're going to mock.134* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or135* goog.testing.Mock.STRICT. The default is STRICT.136* @return {!goog.testing.MockInterface} The mocked global function.137*/138goog.testing.createMethodMock = function(scope, functionName, opt_strictness) {139'use strict';140return goog.testing.MethodMock(scope, functionName, opt_strictness);141};142143144/**145* Convenience method for creating a mock for a constructor. Copies class146* members to the mock.147*148* <p>When mocking a constructor to return a mocked instance, remember to create149* the instance mock before mocking the constructor. If you mock the constructor150* first, then the mock framework will be unable to examine the prototype chain151* when creating the mock instance.152* @param {Object} scope The scope of the constructor to be mocked out.153* @param {string} constructorName The name of the constructor we're going to154* mock.155* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or156* goog.testing.Mock.STRICT. The default is STRICT.157* @return {!goog.testing.MockInterface} The mocked constructor.158*/159goog.testing.createConstructorMock = function(160scope, constructorName, opt_strictness) {161'use strict';162var realConstructor = scope[constructorName];163var constructorMock =164goog.testing.MethodMock(scope, constructorName, opt_strictness);165166// Copy class members from the real constructor to the mock. Do not copy167// the closure superClass_ property (see goog.inherits), the built-in168// prototype property, or properties added to Function.prototype169// TODO(nickreid): Should this work for non-enumerable properties, like are170// created by ES6 classes.171for (var property in realConstructor) {172if (property != 'superClass_' && property != 'prototype' &&173realConstructor.hasOwnProperty(property)) {174constructorMock[property] = realConstructor[property];175}176}177return constructorMock;178};179180181/**182* Convenience method for creating a mocks for a global / top-level function.183* @param {string} functionName The name of the function we're going to mock.184* @param {number=} opt_strictness One of goog.testing.Mock.LOOSE or185* goog.testing.Mock.STRICT. The default is STRICT.186* @return {!goog.testing.MockInterface} The mocked global function.187*/188goog.testing.createGlobalFunctionMock = function(functionName, opt_strictness) {189'use strict';190return goog.testing.GlobalFunctionMock(functionName, opt_strictness);191};192193194