Mock4AS is a simple Mock Object Library for ActionScript3.
The current version of Mock4AS provides a minimalistic Mock Objects library fulfilling the basic Unit Tests mocking needs.
To get started download the latest version of Mock.as and add it to your project.
What is Mock4AS?Mock4as is a
... [More]
simple ActionScript3 library used to verify the interaction between dependent components.
How to use Mock4asUsing a Mock4AS for unit testing involves the following steps:
Create a mock object class 2 Instantiate a mock object
3 Create expectations for the mock
4 Inject the mock
5 Exercise the mock object
6 Verify the the mock expectations
ExampleWe will use the Greeting example to illustrate the basic functionality of Mock4AS.
The Greeting component says Hello in any language.
Greeting uses a Translator component to translate “Hello” from English to the selected language. E.g. greeting.sayHello(“Portuguese”, “Paulo”) should return “Ola Paulo”
ITranslator is an interface containing the translate method – parameters from, to and word, which returns the translated word; e.g translate(“English”, “Portuguese”, “Hello”) would return “Ola”.
Greeting.as
package org.mock4as.samples.greeting {
public class Greeting {
private var translator:ITranslator;
public function Greeting(translator:ITranslator) {
this.translator = translator;
}
public function sayHello(language:String, name:String):String {
return translator.translate("English", language, "Hello") + " " + name;
}
}
} ITranslator.as
package org.mock4as.samples.greeting {
public interface ITranslator {
function translate(from:String, to:String, word:String):String;
}
}At construction time, the Greeting component receives a ITranslator component, a concrete implementation of the ITranslator interface. This simple mechanism is called Constructor Dependency Injection; basically an instance of the dependent component (some ITranslator implementation) is being injected in the Greeting component at construction time.
1. Declare the mockMock4AS offers two mechanisms to implement the mock behavior and verification: subclassing and composition. For clarity sake, the reminder of this page will introduce Mock4AS subclassing based mechanism.
First, subclass org.mock4as.mock and implement the interface of the component you want to mock. You should have something similar to this:
class MockTranslator extends Mock implements ITranslator {Next, set up the structure to record calls to the dependant component. For example, if you are making a mock object to replace a component that implements ISomeInterface, and ISomeInterace has a doSomething(stringArg:String):void method in it, your mock should now look something like this:
public function translate(from:String, to:String, word:String):String
{
record("translate", from, to, word);
return expectedReturnFor("translate");
}The record method call is what is needed to provide the mock implementation of the dependent component.
MockTranslator code:
import org.mock4as.Mock;
import org.mock4as.samples.greeting.ITranslator;
class MockTranslator extends Mock implements ITranslator {
public function translate(from:String, to:String, word:String):String
{
record("translate", from, to, word);
return expectedReturnFor("translate");
}
}2. Create a mock objectYou create a mock the exactly same way you create any other object in AS3.
var mock:MockTranslator = new MockTranslator();3. Create expectations for the mockIn order to verify that your mock has been invoked the way you expect, you first need to set up the expectation in the mock. You do this by evoking the mock API. The mock API provides the following methods for setting expectations:
expects(methodName:String – Tells the mock the name of the expected method call times(numOfTimes:int) – Sets the number of times a particular method should be called withArgs(arg1, arg2, …argN) – Tells the mock what arguments should be passed to a particular method Example: To tell a mock to expect translate to be called with the arguments "English","Portuguese" and "Hello", and to return "Ola" you would write:
mock.expects("translate").withArgs("English","Portuguese","Hello").willReturn("Ola");
4. Inject the MockThe following code shows mock beinf injected during myGreeting construction time.
var myGreeting:Greeting = new Greeting(mock);At construction time, the Greeting component receives mock, a concrete implementation of the ITranslator interface. The mock object which will record and verify expectations set against itself.
5. Exercise the mockYou need to exercise the component invoking he mock in order to verify the mock behavior and expectations. In our example, you need to exercise the Greeting component.
assertEquals("Ola Paulo", myGreeting.sayHello("Portuguese", "Paulo"));6. Verify the the mock expectationsThe last step is to verify the mock expectations.
assertTrue(mock.errorMessage(), mock.success());The success() method checks to see if the methods called match the expectations you have previously set. If mock is invoked the way we expected success() returns true. Otherwise success() will return false.
The errorMessage() method returns a string that describes the reason why the verification failed. Some possible reasons for failure are:
Methods were called that were not expected Methods were not called but they were expected An expected method was called but it was called with arguments that were not expected When the assertTrue(mock.errorMessage(), mock.success()) assertion fails, the test runner will output the string returned by mock.errorMessage() aiding in the effort to provide defect localization.
The complete mock sample codeGreetingTest.as
package org.mock4as.samples.greeting
{
import flexunit.framework.TestCase;
import flexunit.framework.TestSuite;
import org.mock4as.Mock;
public class GreetingTest extends TestCase
{
public function GreetingTest(methodName : String){
super(methodName);
}
public function testGreetingInAnyLanguage():void{
// create the mock
var mock:MockTranslator = new MockTranslator();
// set expectations
mock.expects("translate").withArgs("English","Portuguese","Hello").willReturn("Ola");
// inject the mock
var myGreeting:Greeting = new Greeting(mock);
// execute and assert on greetign and
assertEquals("Ola Paulo", myGreeting.sayHello("Portuguese", "Paulo"));
// verify mock behavior
assertTrue(mock.errorMessage(), mock.success());
}
}
}
// Inner Class
import org.mock4as.Mock;
import org.mock4as.samples.greeting.ITranslator;
class MockTranslator extends Mock implements ITranslator {
public function translate(from:String, to:String, word:String):String
{
record("translate", from, to, word);
return expectedReturnFor("translate");
}
} [Less]