Mockito-Flex meets ASUnit

Well, that’s not a catchy headline, but it does pretty much sum it up. I’ve been playing with Mockito-Flex, a mock object framework for Actionscript 3. It’s great, and made vastly easier to pick up by a Mockito-FlexUnit bridge in the form of a MockitoTestCase that does the hard work of reporting the mocking results and validations in a way that FlexUnit can display.

Of course, FlexUnit does require the Flex framework, which bulks up the whole thing. Oh, and I’m used to using ASUnit. So I’ve written the following class that does the same job as MockitoTestCase, but for ASUnit:

  1. /**
  2.  * The MIT License
  3.  *
  4.  * Copyright (c) 2009 Mockito contributors
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  7.  * and associated documentation files (the "Software"), to deal in the Software without restriction,
  8.  * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
  10.  * subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  15.  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  16.  * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  17.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19.  */
  20.  
  21. package org.mockito {
  22.     import asunit.framework.TestCase;
  23.  
  24.     import org.mockito.api.Matcher;
  25.     import org.mockito.api.MethodSelector;
  26.     import org.mockito.api.MockCreator;
  27.     import org.mockito.api.Stubber;
  28.     import org.mockito.api.Verifier;
  29.  
  30.    
  31.     public class ASUnitMockitoTestCase extends TestCase {
  32.  
  33.         private var _mockClasses:Array;
  34.  
  35.         protected var mockito:Mockito;
  36.        
  37.         public function ASUnitMockitoTestCase(mockClasses:Array, testMethod:String = null)
  38.         {
  39.             _mockClasses = mockClasses;
  40.             super(testMethod);
  41.         }
  42.  
  43.         /**
  44.          * Due to the asynchronous nature of the class generation
  45.          * a test needs to execute from a callback function
  46.          */
  47.         public override function run():void
  48.         {
  49.             if (mockito == null && _mockClasses)
  50.             {
  51.                 mockito = new Mockito();
  52.                 var superRun:Function = super.run;
  53.                 mockito.prepareClasses(_mockClasses, repositoryPreparedHandler);
  54.                 function repositoryPreparedHandler():void
  55.                 {
  56.                     superRun();
  57.                 }
  58.             }
  59.             else
  60.             {
  61.                 super.run();
  62.             }
  63.         }
  64.        
  65.        
  66.  
  67.         /**
  68.          * Constructs mock object
  69.          * @param clazz a class of the mock object
  70.          * @param constructorArgs constructor arguments required to create mock instance
  71.          * @param name a name used in various output
  72.          * @return a mocked object
  73.          */
  74.         public function mock(classToMock:Class, name:String = null, constructorArgs:Array = null):Object
  75.         {
  76.             return mockito.mock(classToMock, name, constructorArgs);
  77.         }
  78.  
  79.         /**
  80.          * A starter function for verification of executions
  81.          * If you dont specify the verifier, an equivalent of times(1) is used.
  82.          * @param verifier object responsible for verification of the following execution
  83.          */
  84.         public function verify(verifier:Verifier = null):MethodSelector
  85.         {
  86.             return mockito.verify(verifier);
  87.         }
  88.  
  89.         /**
  90.          * A starter function for stubbing
  91.          * @param methodCallToStub call a method to stub as an argument
  92.          * @return an object providing stubbing options
  93.          */
  94.         public function given(methodCallToStub:*):Stubber
  95.         {
  96.             return mockito.given(methodCallToStub);
  97.         }
  98.  
  99.         /**
  100.          * @private
  101.          */
  102.         protected function get mockCreator():MockCreator
  103.         {
  104.             return mockito;
  105.         }
  106.  
  107.         /**
  108.          * Matches any argument including <code>null</code>
  109.          */
  110.         public function any():*
  111.         {
  112.             return mockito.any();
  113.         }
  114.  
  115.         /**
  116.          * Equality matcher
  117.          * Example:
  118.          * <listing>
  119.          * verify(never()).that(system.login(eq("root")));
  120.          * </listing>
  121.          */
  122.         public function eq(expected:*):*
  123.         {
  124.             return mockito.eq(expected);
  125.         }
  126.  
  127.         /**
  128.          * A fluent interface for making sure call hasn't happened
  129.          * Example:
  130.          * <listing>
  131.          * verify(never()).that(operator.execute());
  132.          * </listing>
  133.          */
  134.         public function never():Verifier
  135.         {
  136.             return mockito.never();
  137.         }
  138.  
  139.         /**
  140.          * A fluent interface for counting calls
  141.          * Example:
  142.          * <listing>
  143.          * verify(times(2)).that(operator.execute());
  144.          * </listing>
  145.          */
  146.         public function times(expectedCallsCount:int):Verifier
  147.         {
  148.             return mockito.times(expectedCallsCount);
  149.         }
  150.  
  151.         /**
  152.          * A fluent interface for custom matcher
  153.          * Example:
  154.          * <listing>
  155.          * verify().that(system.login(argThat(new HashOnlyCapitalLettersMatcher())));
  156.          * </listing>
  157.          *
  158.          * A good practice is to create a matcher recording function somewhere and name it
  159.          * after the matcher. It's important to return a wildcard from the function to let it
  160.          * work with any arugment of the function
  161.          * <listing>
  162.          * function hasOnlyCapitalLetters():*
  163.          * {
  164.          *     argThat(new HashOnlyCapitalLettersMatcher());
  165.          * }
  166.          * </listing>
  167.          */
  168.         public function argThat(matcher:Matcher):*
  169.         {
  170.             return mockito.argThat(matcher);
  171.         }
  172.     }
  173. }

I’ve built this against ASUnit3, and it appears to be running fine. As you can see, it’s release under the MIT license, as is Mockito-Flex. I’d appreciate any feedback that’s going, so have a play and let me know …

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

2 Comments

  1. Kris — July 31, 2009 @ 8:53 am

    James,

    Great work! I'll add it to the integrations in the tutorial.

    Regards,
    Kris

  2. Luke Bayes — July 31, 2009 @ 7:31 pm

    Thanks James –

    This looks great!

RSS feed for comments on this post. TrackBack URI

Leave a comment