| // Copyright 2008 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| goog.setTestOnly('goog.testing.MockClassFactoryTest'); |
| goog.require('goog.testing'); |
| goog.require('goog.testing.MockClassFactory'); |
| goog.require('goog.testing.jsunit'); |
| goog.provide('fake.BaseClass'); |
| goog.provide('fake.ChildClass'); |
| goog.provide('goog.testing.MockClassFactoryTest'); |
| |
| // Classes that will be mocked. A base class and child class are used to |
| // test inheritance. |
| fake.BaseClass = function(a) { |
| fail('real object should never be called'); |
| }; |
| |
| fake.BaseClass.prototype.foo = function() { |
| fail('real object should never be called'); |
| }; |
| |
| fake.BaseClass.prototype.toString = function() {return 'foo';}; |
| |
| fake.BaseClass.prototype.toLocaleString = function() {return 'bar';}; |
| |
| fake.ChildClass = function(a) { |
| fail('real object should never be called'); |
| }; |
| goog.inherits(fake.ChildClass, fake.BaseClass); |
| |
| fake.ChildClass.staticFoo = function() { |
| fail('real object should never be called'); |
| }; |
| |
| fake.ChildClass.prototype.bar = function() { |
| fail('real object should never be called'); |
| }; |
| |
| fake.ChildClass.staticProperty = 'staticPropertyOnClass'; |
| |
| function TopLevelBaseClass() { |
| } |
| |
| var mockClassFactory = new goog.testing.MockClassFactory(); |
| var matchers = goog.testing.mockmatchers; |
| |
| function tearDown() { |
| mockClassFactory.reset(); |
| } |
| |
| function testGetStrictMockClass() { |
| var mock1 = mockClassFactory.getStrictMockClass(fake, fake.BaseClass, 1); |
| mock1.foo(); |
| mock1.$replay(); |
| |
| var mock2 = mockClassFactory.getStrictMockClass(fake, fake.BaseClass, 2); |
| mock2.foo(); |
| mock2.$replay(); |
| |
| var mock3 = mockClassFactory.getStrictMockClass(fake, fake.ChildClass, 3); |
| mock3.foo(); |
| mock3.bar(); |
| mock3.$replay(); |
| |
| var instance1 = new fake.BaseClass(1); |
| instance1.foo(); |
| mock1.$verify(); |
| |
| var instance2 = new fake.BaseClass(2); |
| instance2.foo(); |
| mock2.$verify(); |
| |
| var instance3 = new fake.ChildClass(3); |
| instance3.foo(); |
| instance3.bar(); |
| mock3.$verify(); |
| |
| assertThrows(function() {new fake.BaseClass(-1)}); |
| assertTrue(instance1 instanceof fake.BaseClass); |
| assertTrue(instance2 instanceof fake.BaseClass); |
| assertTrue(instance3 instanceof fake.ChildClass); |
| } |
| |
| function testGetStrictMockClassCreatesAllProxies() { |
| var mock1 = mockClassFactory.getStrictMockClass(fake, fake.BaseClass, 1); |
| // toString(), toLocaleString() and others are treaded specially in |
| // createProxy_(). |
| mock1.toString(); |
| mock1.toLocaleString(); |
| mock1.$replay(); |
| |
| var instance1 = new fake.BaseClass(1); |
| instance1.toString(); |
| instance1.toLocaleString(); |
| mock1.$verify(); |
| } |
| |
| function testGetLooseMockClass() { |
| var mock1 = mockClassFactory.getLooseMockClass(fake, fake.BaseClass, 1); |
| mock1.foo().$anyTimes().$returns(3); |
| mock1.$replay(); |
| |
| var mock2 = mockClassFactory.getLooseMockClass(fake, fake.BaseClass, 2); |
| mock2.foo().$times(3); |
| mock2.$replay(); |
| |
| var mock3 = mockClassFactory.getLooseMockClass(fake, fake.ChildClass, 3); |
| mock3.foo().$atLeastOnce().$returns(5); |
| mock3.bar().$atLeastOnce(); |
| mock3.$replay(); |
| |
| var instance1 = new fake.BaseClass(1); |
| assertEquals(3, instance1.foo()); |
| assertEquals(3, instance1.foo()); |
| assertEquals(3, instance1.foo()); |
| assertEquals(3, instance1.foo()); |
| assertEquals(3, instance1.foo()); |
| mock1.$verify(); |
| |
| var instance2 = new fake.BaseClass(2); |
| instance2.foo(); |
| instance2.foo(); |
| instance2.foo(); |
| mock2.$verify(); |
| |
| var instance3 = new fake.ChildClass(3); |
| assertEquals(5, instance3.foo()); |
| assertEquals(5, instance3.foo()); |
| instance3.bar(); |
| mock3.$verify(); |
| |
| assertThrows(function() {new fake.BaseClass(-1)}); |
| assertTrue(instance1 instanceof fake.BaseClass); |
| assertTrue(instance2 instanceof fake.BaseClass); |
| assertTrue(instance3 instanceof fake.ChildClass); |
| } |
| |
| function testGetStrictStaticMock() { |
| var staticMock = mockClassFactory.getStrictStaticMock(fake, |
| fake.ChildClass); |
| var mock = mockClassFactory.getStrictMockClass(fake, fake.ChildClass, 1); |
| |
| mock.foo(); |
| mock.bar(); |
| staticMock.staticFoo(); |
| mock.$replay(); |
| staticMock.$replay(); |
| |
| var instance = new fake.ChildClass(1); |
| instance.foo(); |
| instance.bar(); |
| fake.ChildClass.staticFoo(); |
| mock.$verify(); |
| staticMock.$verify(); |
| |
| assertTrue(instance instanceof fake.BaseClass); |
| assertTrue(instance instanceof fake.ChildClass); |
| assertThrows(function() { |
| mockClassFactory.getLooseStaticMock(fake, fake.ChildClass); |
| }); |
| } |
| |
| function testGetStrictStaticMockKeepsStaticProperties() { |
| var OriginalChildClass = fake.ChildClass; |
| var staticMock = mockClassFactory.getStrictStaticMock(fake, |
| fake.ChildClass); |
| assertEquals(OriginalChildClass.staticProperty, |
| fake.ChildClass.staticProperty); |
| } |
| |
| function testGetLooseStaticMockKeepsStaticProperties() { |
| var OriginalChildClass = fake.ChildClass; |
| var staticMock = mockClassFactory.getLooseStaticMock(fake, |
| fake.ChildClass); |
| assertEquals(OriginalChildClass.staticProperty, |
| fake.ChildClass.staticProperty); |
| } |
| |
| function testGetLooseStaticMock() { |
| var staticMock = mockClassFactory.getLooseStaticMock(fake, |
| fake.ChildClass); |
| var mock = mockClassFactory.getStrictMockClass(fake, fake.ChildClass, 1); |
| |
| mock.foo(); |
| mock.bar(); |
| staticMock.staticFoo().$atLeastOnce(); |
| mock.$replay(); |
| staticMock.$replay(); |
| |
| var instance = new fake.ChildClass(1); |
| instance.foo(); |
| instance.bar(); |
| fake.ChildClass.staticFoo(); |
| fake.ChildClass.staticFoo(); |
| mock.$verify(); |
| staticMock.$verify(); |
| |
| assertTrue(instance instanceof fake.BaseClass); |
| assertTrue(instance instanceof fake.ChildClass); |
| assertThrows(function() { |
| mockClassFactory.getStrictStaticMock(fake, fake.ChildClass); |
| }); |
| } |
| |
| function testFlexibleClassMockInstantiation() { |
| // This mock should be returned for all instances created with a number |
| // as the first argument. |
| var mock = mockClassFactory.getStrictMockClass(fake, fake.ChildClass, |
| matchers.isNumber); |
| mock.foo(); // Will be called by the first mock instance. |
| mock.foo(); // Will be called by the second mock instance. |
| mock.$replay(); |
| |
| var instance1 = new fake.ChildClass(1); |
| var instance2 = new fake.ChildClass(2); |
| instance1.foo(); |
| instance2.foo(); |
| assertThrows(function() { |
| new fake.ChildClass('foo'); |
| }); |
| mock.$verify(); |
| } |
| |
| function testMockTopLevelClass() { |
| var mock = mockClassFactory.getStrictMockClass(goog.global, |
| goog.global.TopLevelBaseClass); |
| } |