All Projects → badoo → MockJS

badoo / MockJS

Licence: other
No description, website, or topics provided.

Programming Languages

javascript
184084 projects - #8 most used programming language

MockJS

JavaScript object mocking library based on Mockito syntax for JS unit testing. It goes a bit further by implementing some cool syntax you can achieve in JavaScript using ECMA5 object properties and allowing you to handle mocking global scope functions and match calls on different contexts.

Installation

  • Include /src/Mock.js into your tests runtime
  • Mock will automatically attach itself to the "window" scope (browser) if it exists

For specific unit testing tools:

  • you can use Mock.hookTo(context); to import MockJS tools into your testing scope.
  • Currently supports context = "screwunit", "JsUnitTest", "jsUnity", "jSpec", "JsTestDriver", "YUITest", "QUnit";

Or you can send your own context object:

Mock.hookTo(MyTestingTool.globalTestScope);

Quick test / check:

  • check and run /testception/index.html in your browser (outputs test results in console) Note: the small TestSuite included in testception is a very simplistic tool used to test MockJS itself - MockJS is completely standalone.

Documentation

Documentation below is divided into 2 main sections:

  • Mockito Classics - what you did in Mockito and how to do it in MockJS;
  • MockJS Specifics - specific features for mocking JavaScript;

Docs 1. Mockito Classics

Your Mockito classics (rewritten directly from Mockito's documentation):

1. Verify interactions

var mockArray = Mock([]);   //create the mock object

mockArray.push("one");

verify( Acts.once, mockArray.push("one") );

1. Stubbing method calls

when( mockArray.push("one") ).thenReturn(1);

console.log( mockArray.push("one") );   //prints "1"

verify( Acts.once, mockArray.push("one") );

3. Argument matchers

when( mockArray.push(Match.anything) ).thenReturn("hello!");

console.log( mockArray.push("one") );   //prints "hello!"
console.log( mockArray.push(999) );   //prints "hello!"
    
//look into 102. for more information

4. Verifying exact number of invocations / at least x / never

verify( Acts.never, mockArray.push("one") );        //ok
    
mockArray.push("one");
verify( Acts.once, mockArray.push("one") );         //ok
verify( Acts.atLeast(1), mockArray.push("one") );   //ok
    
mockArray.push("one");
mockArray.push("one");
verify( Acts.atMost(2), mockArray.push("one") );    //fails
    
//look into 103. for more information

5. Stubbing void methods with exceptions

when( mockArray.push(Match.anything) ).thenThrow("Hi, I am an expcetion");
    
mockArray.push("something");    //throws our exception

11. Stubbing with callbacks

when( mockArray.push(Match.anything) ).thenReturn(function(arg){ 
    console.log("array.push('"+arg+"') called!");
    return "hello!"; 
});
    
console.log( mockArray.push("one") );   //prints "array.push('one') called!" and "hello!"

12. thenReturn() | thenThow() | thenAnswer() | thenNothing() | thenCallRealMethod() family of methods

Currently implemented:

  • thenReturn()
  • thenThow()

Not Yet Implemented:

  • thenNothing()
  • thenCallRealMethod()

Unnecessary in JS: thenAnswer()

15. Capturing arguments for further assertions

//All return callbacks support it by default - take a look at example 11.

18. Troubleshooting & validating framework usage

You should know that MockJS validates if you use it correctly all the time. You have more questions please refer to our issues section on github.

26. Mocking details

Mock.isMock(someObject);

Not Yet Implemented:

  • Mock.isSpy

Docs 2. MockJS specific features

100. Mock in-scope functions

function sum(a, b){
    return a+b;
}
    
var mockSum = Mock(sum);
    
mockSum(5, 5); //returns undefined (default)

101. Match contexts

when( mockArray.push.apply(Match.anyContext, [Match.anything]) ).thenReturn("something");
    
mockArray.push.apply([], ["one"]);
    
verify( Acts.once, mockArray.push.apply(Match.anyContext, [Match.anything]) );

102. Matchers (Match)

//argument matchers
Match.anyString         //argument is a string
Match.anyInt            //argument is an integer
Match.anyNumber         //argument is a number
Match.anyFunction       //argument is a function
Match.anything          //argument is not undefined  
    
Match.everything        //special matcher - all arguments from this point on will be accepted
                        //eg. when( foo("a", Match.everything) ) will match foo("a"), foo("a", "one"), foo("a", 1, 2, 3, 4, 5, 6);
                            
                            
//context matcher
Match.anyContext        //all contexts will be accepted

103. Call Counters (Acts)

Acts.times(x);  //verifies call acted exactly x number of times
Acts.never      //never happens (short for Acts.times(0))
Acts.once       //acts once (short for Acts.times(1))
Acts.atLeast(x) //acts at least x times
Acts.atMost(x)  //acts at most x times
    
//Note: the following syntax should not be used:
var a = Acts.never
verify( a, foo() );                 //works 1st time
verify( a, foo("one") );            //throws unexpected action in MockJS on all further uses
    
    
verify( Acts.never, foo("one") );   //always use the complete API syntax

104. Custom argument matchers

function myClass(){
}
    
var matchObjectClass = function(arg){
    return arg instanceof myClass;
}
    
when( foo(matchObjectClass) ).thenReturn("something");
    
foo(new myClass());  //returns "something"
    
verify( Acts.once, foo(matchObjectClass) ); //verifies correctly

105. Save and restore global references

//let's consider our global function foo
var foo = function(a){
    alert(a);
    return "hello";
}
    
foo = Mock.andSave(foo, "myFoo");        //mocks function foo but keeps a reference for teardown (below)
    
when( foo(Match.anything) ).thenReturn("hello");
    
console.log( foo("hey") );         //prints "hello" into console
    
    
//teardown
foo = Mock.teardown("myFoo");    //sets foo back to the original function
    
foo("hey");         //alerts "hey"

106. Mock.new() - create mocks for inacessible objects

//Consider the function we need to mock:
function $(a){ 
    var privateObject = {
        whisper:function(){
            console.log(a);
            return true;
        },
        say:function(){
            alert(a);
            return true;
        }   
    }
        
    return privateObject;
}
// Notice we cannot get a "mockable" instance of privateObject
// but we do know it is going to have a method "say"
    
//our function being tested
function iNeedTesting(){
    var check = $("hello");
        
    if(check.whisper() && check.say()) console.log("works!");
}
    
    
    
    
//let's mock the main wrapper
$ = Mock($);
    
var privateObject = Mock.new(["whisper", "say"]);       //create a mock object with methods "whisper" and "say"
    
when( $("hello") ).thenReturn(mockPrivateObject);
when( privateObject.whisper() ).thenReturn(true);
when( privateObject.say() ).thenReturn(true);
    
iNeedTesting(); //run our function being tested - prints out "works!" to console
    
verify(Acts.once, $("hello"));
verify(Acts.once, privateObject.whisper());
verify(Acts.once, privateObject.say());
    
//all ok

Other Mockito features status

Stuff on Mockito documentation that we haven't implemented yet

  • 6. Verification in order
  • 7. Making sure interaction(s) never happened on mock
  • 8. Finding redundant invocations
  • 10. Stubbing consecutive calls (iterator-style stubbing)
  • 13. Spying on real objects
  • 14. Changing default return values of unstubbed invocations
  • 16. Real partial mocks
  • 17. Resetting mocks
  • 19. Aliases for behavior driven development
  • 20. Serializable mocks
  • 21. New annotations: @Captor, @Spy, @InjectMocks //Note: Probably Not Applicable
  • 22. Verification with timeout
  • 23. Automatic instantiation of @Spies, @InjectMocks and constructor injection goodness //Note: Probably Not Applicable
  • 24. One-liner stubs
  • 25. Verification ignoring stubs
  • 27. Delegate calls to real instance //Note: Probably Not Applicable
  • 28. MockMaker API //Note: Probably Not Applicable

Something extra we would like to do:

  • 107. Make it available as a npm package (Node.js)

Pull requests anyone? :p

Credits

This special cocktail is brought to you by Badoo Trading Limited and it is released under the MIT License

Created by Carlos Ouro

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].