TestCase - Documentation

Index

The methods mocking functionality.

In general there are only two methods for the mocking stuffs. mockup(object, method_name, mock) (or mockUp(...)) to mock an object's method up and undoMockup(object, method_name) (undo_mockup(...)) to get the original method back.

Example

Say we have got an element with a method which will hide the element smoothly by calling an effect library. The problem here is that the action will take time but we need to test it in the run-time. So we mock up the effect library method so it was display the elemen immidiately. testAnObjectMocking: function() { // this should be somewhere in your code var some_element = $('some-element'); some_element.hideSmoothly = function() { Effect.Fade(this, {duration: 0.4}); }; this.mockUp(Effect, 'Fade', function() { some_element.style.display = 'none'; }); this.assert_visible(some_element); some_element.hideSmoothly(); this.assert_hidden(some_element); }

NOTE

In general you can mockup an object's methods and a class prototype methods, but note, the instance level mocks have got a higher priority than the prototype ones. So if you have mocked up an prototype with one mock1 and the prototype object with mock2, then for all the prototype instances (future and existing ones) you'll have the mock1 working on, but for the object which you have mocked up with mock2, you'll have the mock2 function working.

var AClass = Class.create(); AClass.prototype = { sayHello: function() { alert('hello'); } }; ...... testAClassSayHello: function() { var obj1 = new AClass(); var obj2 = new AClass(); this.mockUp(obj1, 'sayHello', function() { alert('hi there'); }); this.mockUp(AClass.prototype, 'sayHello', function() { alert('mocked hello'); }); var obj3 = new AClass(); obj1.sayHello(); // <- will say 'hi there' obj2.sayHello(); // <- will say 'mocked hello' obj3.sayHello(); // <- will say 'mocked hello' }

TestCase 2.0 mocking features.

Since the version 2.0, the library has some important updates in the mocking system.

First, the wrapping mocking methods were added. Those methods apply arguments for mocking as usual mockUp method, and additionaly get a callback function attribute. The methods runs the mockup procedure, then executes the given callback function in the given scope, and after all, undos the maden mock up.

with_mocked(Object object, String method_name, Function mock, Function callback[, Object scope])

And we have got some aliaces for the method withMocked(), with_mock(), withMock()

Example

test_mocked_function: function() { var obj = { result: function() { return 'Something terrible'; } }; this.with_mocked(obj, 'result', function() { return 'acceptable'; }, // inside the function the object will use the mocked method function() { this.assert_equal('acceptable', obj.result()); }, this // <- optional scope element ); // outside the call the object will use the native method this.assert_equal('Something terrible', obj.result()); }

Effects Mocking

The second important change is that dispite the fact that the library no more depndent on the Prorotype library we don't forget our dear friends. You still can use the effects mocking feature as you used to:

test_menu: function() { this.mockup_effects(); this.assert_hidden('menu-element'); Effect.BlindDown('menu-element'); this.assert_visible('menu-element'); this.undo_effects_mockup(); }

More important now you can do just the same the MooTools framework. Use just the same methods mockup_effects() and undo_effects_mockup() and all your MooTools effects will happened immidiatelly. You don't need to change anything, the library will automatically find out which framework you are using.

And a wrapping method for the effects mocking has been added to. It works a similar way as the mocking one.

test_menu: function() { this.with_mocked_effects(function() { this.assert_hidden('menu-element'); Effect.BlindDown('menu-element'); this.assert_visible('emnu-element'); }, this); }

Ajax mocking

And the third most important thing about the new mocking system is the ajax-requests mocking. Yes, dear sir, we have got the candy. Currently, it works with the Prototype and MooTools frameworks.

The principle is simple, you decide what the request should return in hash like this. You can support any numbers of keys you like, all of them are optional

{ text: 'some text you like', // '' by default xml: your_xml_object, // null by default status: 200, // 200 by default headers: ['Content-type: text/xml'] // [] by default }

And an average ajax-test with mocking might looks like that.

test_ajax_load: function() { var block = $('some-block'); this.assert_equal('', block.innerHTML); // say the block is empty by default this.mockup_ajax({text: '<p>some text</p>'}); // doing some call new Ajax.Updater('some-block', '/some/url'); // the block will be updated right now this.assert_equal('<p>some text</p>', block.innerHTML); this.undo_ajax_mockup(): }

And sure we have added a wrapped ajax-mocking method. It will mockup your ajax engine on the beginning and undo the mockup at the end.

test_ajax_load: function() { this.with_mocked_ajax({ status: 404, text: 'not found' }, function() { // all the ajax calls here will return status 404 and test 'not found'. }, this ); }