drewbourne / mockolate Goto Github PK
View Code? Open in Web Editor NEWfake chocolate, mock objects and test spies for AS3
Home Page: http://mockolate.org/
License: MIT License
fake chocolate, mock objects and test spies for AS3
Home Page: http://mockolate.org/
License: MIT License
As a convenience allow stubbing and mocking multiple methods or properties by providing a RegExp or Matcher as the method name.
// using a RegExp
stub(permissions).method(/can(Edit|Show|Delete)/).returns(true);
// using a Matcher
var eventDispatcherMethods:Array = ['addEventListener', 'dispatchEvent', 'hasEventListener', 'removeEventListener', 'willTrigger'];
stub(permissions).method(inArray(eventDispatcherMethods)).anyArgs().pass();
Hi Drew
Is there anyway to mock a channelset.login and logout? I have the following code in my delegate called from my controller, which I would like to confirm works. I tried Brian LeGross's RPCStubs, but he confirmed that he has not yet implemented channelsets, so just wondering if this is something you deal with?
Thanks
Des
public class LoginController extends AbstractController
{
[Inject] // Wire in the model
public var loginModel:LoginModel;
[Inject] // Wire in the delegate for remote calls
public var loginDelegate:LoginDelegate;
[Dispatcher] // Allows this class to dispatch events.
public var eventDispatcher:IEventDispatcher;
public function login():void {
// Handle successful login.
var loginResultEvent:Function = function(event:ResultEvent ):void {
eventDispatcher.dispatchEvent( new AuthenticationEvent (AuthenticationEvent.LOGGEDIN));
}
// Handle login failure.
var loginFaultEvent:Function = function(event:FaultEvent):void {
this.eventDispatcher.dispatchEvent(new AuthenticationEvent (AuthenticationEvent.LOGIN_FAIL));
}
// Log into the Remote server channelset login
executeServiceCall(loginDelegate.login (loginModel.username,loginModel.password), loginResultEvent, loginFaultEvent);
}
}
public class LoginDelegate
{
private var channelSet:ChannelSet;
public function login(username:String, password:String):AsyncToken
{
channelSet = ServerConfig.getChannelSet(authenticationService.destination);
return channelSet.login(username, password);
}
}
for example:
verify(instance).method('notCalled').once();
currently fails with the message: Error: no invocations as METHOD
, when it really should include the name of the method, the type of instance, and its mockolate name if any.
Proxy subclasses like WebService are used with dynamic methods that do not appear in the public namespace of describeType. These dynamic method invocations should be forwarded to Mockolate for mocking and stubbing. Implementation will be similar to the MockolateProxy.
When using the MockolateRule it should hook into strict()
and nice()
and verify instances created with those in VerifyMockInstance.
Hi Drew
I have written a test case which relies heavily on mockolate and have all my tests running and passing through the FlexUnit view in FlashBuilder4.5.
I also have an ant task that executes all my flex unit tests via a CIListener and generates a report. Weird thing is, when I run the tests through ant (and eventually on my build server) the ones using mockolate error ....even though they were working in Flashbuilder.
I have made sure FB and ant are both using the same version of Flex Unit 4.1 RC2.
The two errors I seem to be getting when running the ant script are:
Error #1065: Variable org.hamcrest.collection::emptyArray is not defined.
ReferenceError: Error #1065: Variable org.hamcrest.collection::emptyArray is not defined.
at mockolate.ingredients::Mockolatier/prepare()[/Users/drew/Development/workspace-burrito/mockolate/mockolate/src/mockolate/ingredients/Mockolatier.as:81]
at mockolate.runner.statements::PrepareMockClasses/evaluate()[/Users/drew/Development/workspace-burrito/mockolate/mockolate/src/mockolate/runner/statements/PrepareMockClasses.as:50]
AND
A proxy for uk.digitalkeystone.core.view.components::INavButtons has not been prepared yet
ArgumentError: A proxy for uk.digitalkeystone.core.view.components::INavButtons has not been prepared yet
at org.floxy::ProxyRepository/create()[/Users/drew/Development/workspace-burrito/floxy/floxy/src/org/floxy/ProxyRepository.as:55]
at mockolate.ingredients.floxy::FloxyMockolateFactory/create()[/Users/drew/Development/workspace-burrito/mockolate/mockolate/src/mockolate/ingredients/floxy/FloxyMockolateFactory.as:57]
This is my test case for a RL mediator, the actual mediator and view are both really simple, but let me know if you need to see the source code.
public class NavButtonsMediatorTest
{
[Rule]
public var rule:MockolateRule = new MockolateRule();
[Mock]
public var view:INavButtons;
private var classUnderTest:NavButtonsMediator;
[Before]
public function setUp():void
{
classUnderTest = new NavButtonsMediator();
classUnderTest.backButtonClickedOut = new BackButtonClickedSignal();
classUnderTest.nextButtonClickedOut = new NextButtonClickedSignal();
classUnderTest.screenIndexChangedIn = new ScreenIndexChangedSignal();
classUnderTest.toggleNavigationEnabledIn = new ToggleNavigationEnabledSignal();
classUnderTest.view = nice(INavButtons);
mock(classUnderTest.view).getter("backButtonClickedOut").returns(new BackButtonClickedSignal());
mock(classUnderTest.view).getter("nextButtonClickedOut").returns(new NextButtonClickedSignal());
mock(classUnderTest.view).setter("currentIndex").arg(int);
mock(classUnderTest.view).setter("total").arg(uint);
mock(classUnderTest.view).setter("enabled").arg(Boolean);
classUnderTest.onRegister();
}
[After]
public function tearDown():void
{
classUnderTest.onRemove();
classUnderTest = null;
}
[BeforeClass]
public static function setUpBeforeClass():void
{
}
[AfterClass]
public static function tearDownAfterClass():void
{
}
//--------------------------------------------------------------------------
//
// Verify that the total and currentIndex of the view are set in response to an incoming ScreenIndexChangedSignal
//
//--------------------------------------------------------------------------
[Test(order="1")]
public function screenIndexChangedIn__viewTotalAndCurrentSet():void
{
// Arrange
// Act
classUnderTest.screenIndexChangedIn.dispatch(0,4);
// Assert
assertThat(classUnderTest.view, received().setter("total").arg(4).times(1));
assertThat(classUnderTest.view, received().setter("currentIndex").arg(0).times(1));
}
//--------------------------------------------------------------------------
//
// Verify that BackButtonClickedSignal is dispatched when the view back button is clicked
//
//--------------------------------------------------------------------------
[Test(async,order="2")]
public function backButtonClicked__signalForwarded():void
{
// Arrange
// Assert
proceedOnSignal(this, classUnderTest.backButtonClickedOut);
// Act
classUnderTest.view.backButtonClickedOut.dispatch();
}
//--------------------------------------------------------------------------
//
// Verify that NextButtonClickedSignal is dispatched when the view next button is clicked
//
//--------------------------------------------------------------------------
[Test(async,order="3")]
public function nextButtonClicked__signalForwarded():void
{
// Arrange
// Assert
proceedOnSignal(this, classUnderTest.nextButtonClickedOut);
// Act
classUnderTest.view.nextButtonClickedOut.dispatch();
}
//--------------------------------------------------------------------------
//
// Verify that the view is enabled or disabled based on the incoming ToggleNavigationEnabledSignal payload
//
//--------------------------------------------------------------------------
[Test(order="4")]
public function toggleNavigationEnabledIn_true_viewEnableSet():void
{
// Arrange
// Act
classUnderTest.toggleNavigationEnabledIn.dispatch(true);
// Assert
assertThat(classUnderTest.view, received().setter("enabled").arg(true).times(1));
}
[Test(order="5")]
public function toggleNavigationEnabledIn_false_viewEnableSet():void
{
// Arrange
// Act
classUnderTest.toggleNavigationEnabledIn.dispatch(false);
// Assert
assertThat(classUnderTest.view, received().setter("enabled").arg(false).times(1));
}
}
I could of course be massively mis-using mockolate or flex unit so any guidance you could offer will be much appreciated.
Cheers
Gavin
Exclude HTTPServiceDecorator and other classes that have Flex dependencies.
Hi,
Am getting the below exception when trying to mock a class. I'm not able to work out why I'm not meeting the expectation? time.execute() calls the mocks makeRequest() method.
Any help is gratefully appreciated.
The test case is:
[Test(async)]
public function testCallToGetTimeReturnsDateObject() : void {
var dvbService:DVBIPBridgeService = nice(DVBIPBridgeService);
record(dvbService);
expect(dvbService.makeRequest(expectArg({command : "time"})));
replay(dvbService);
var time : TimeCommand = new TimeCommand(dvbService);
time.execute();
verify(dvbService);
}
The code under test is:
public class TimeCommand extends EventDispatcher {
static const REQUEST_SUCCESS:String = "onRequestSuccess";
private var _service:DVBIPBridgeService;
public function TimeCommand(service : DVBIPBridgeService) {
_service = service;
_service.addEventListener(DVBIPBridgeService.REQUEST_COMPLETE, onRequestComplete);
}
public function execute():void {
_service.makeRequest({command : "time"});
}
private function onRequestComplete(event:DVBIPBridgeServiceSuccessEvent):void {
var date : Date = new Date();
date.setTime(event.data.time * 1000);
dispatchEvent(new TimeCommandSuccess(REQUEST_SUCCESS, date));
}
}
1 unmet Expectation
bbc.tvp.dvbipbridge::DVBIPBridgeService#makeRequest(<[object Object]>)
Error: 1 unmet Expectation
bbc.tvp.dvbipbridge::DVBIPBridgeService#makeRequest(<[object Object]>)
at mockolate.ingredients::MockingCouverture/mockolate.ingredients.only::verify()[C:\Users\James\IdeaProjects\Mocks\MocklateSWC\src\mockolate\ingredients\MockingCouverture.as:990]
at mockolate.ingredients::Mockolate/mockolate.ingredients.only::verify()[C:\Users\James\IdeaProjects\Mocks\MocklateSWC\src\mockolate\ingredients\Mockolate.as:210]
at mockolate.ingredients::Mockolatier/verify()[C:\Users\James\IdeaProjects\Mocks\MocklateSWC\src\mockolate\ingredients\Mockolatier.as:148]
at mockolate.ingredients::MockolatierMaster$/verify()[C:\Users\James\IdeaProjects\Mocks\MocklateSWC\src\mockolate\ingredients\MockolatierMaster.as:85]
at global/mockolate::verify()[C:\Users\James\IdeaProjects\Mocks\MocklateSWC\src\mockolate\verify.as:27]
at bbc.tvp.dvbipbridge::TimeCommandTest/testCallToGetTimeReturnsDateObject()[D:\Dev\Code\Flash\AS3\Xmpp\DVBIPBridge\src\test\flex\bbc\tvp\dvbipbridge\TimeCommandTest.as:53]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at flex.lang.reflect::Method/apply()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/flex/lang/reflect/Method.as:244]
at org.flexunit.runners.model::FrameworkMethod/invokeExplosively()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/runners/model/FrameworkMethod.as:201]
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/InvokeMethod.as:72]
at org.flexunit.internals.runners.statements::ExpectAsync/evaluate()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/ExpectAsync.as:595]
at org.flexunit.internals.runners.statements::RunBeforesInline/handleSequenceExecuteComplete()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/RunBeforesInline.as:85]
at org.flexunit.token::AsyncTestToken/sendResult()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/token/AsyncTestToken.as:107]
at org.flexunit.internals.runners.statements::AsyncStatementBase/sendComplete()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/AsyncStatementBase.as:76]
at org.flexunit.internals.runners.statements::StatementSequencer/sendComplete()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/StatementSequencer.as:172]
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/StatementSequencer.as:145]
at org.flexunit.token::AsyncTestToken/sendResult()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/token/AsyncTestToken.as:107]
at org.flexunit.internals.runners.statements::ExpectAsync/sendComplete()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/ExpectAsync.as:560]
at org.flexunit.internals.runners.statements::ExpectAsync/handleAsyncEventFired()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/internals/runners/statements/ExpectAsync.as:431]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at org.flexunit.async::AsyncHandler/handleEvent()[/Users/abourne/Workspaces/movideo/flexunit/FlexUnit4/src/org/flexunit/async/AsyncHandler.as:156]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at SetIntervalTimer/onTimer()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Drew,
I've just started using Mockolate, which seems to me to be the most fully featured Flex mocking framework out there, and I have been wrestling with getting a mock HttpService working.
Here's the consumer of the service:
public class LoadEmployeesDelegate
{
private var responder : IResponder;
public var service : HTTPService;
public function LoadEmployeesDelegate( responder : IResponder )
{
this.service = new HTTPService();
this.service.url="assets/Employees.xml";
this.responder = responder;
}
public function loadEmployeesService() : void
{
var token:AsyncToken = service.send();
token.addResponder( responder );
}
}
The first approach I used was:
[Rule]
public var rule:MockolateRule = new MockolateRule();
[Mock]
public var httpService : HTTPService;
...
// no send parameters so set to null
// don't care about the fault details so set blank
mock(httpService).asHTTPService().send(null).fault("","","");
This didn't work because it failed to return an AsyncToken :(
I then tried the following which did work :)
var token:AsyncToken = new AsyncToken();
var faultEvent:FaultEvent = new FaultEvent(FaultEvent.FAULT, false, false, new Fault("", "", ""), token);
mock(httpService).method("send").returns(token).answers(new FaultAnswer(token, faultEvent));
My question is, why did the first example fail, and what is the purpose of the asHTTPService() method. Is there any way to refactor the failing example so that it returns the AsyncToken without the verbose setup of the second?
Many thanks,
Murray
Hi,
I've written the following unit test following the example in StubbingHttpService.as file. When I run it it passes which it shouldn't because the HTTPService.send() method isn't being called within the actual code. My expectation is for an ExpectionError to be thrown.
What am I doing wrong?
[RunWith("mockolate.runner.MockolateRunner")]
public class DVBIPBridgeServiceTest {
[Mock]
public var httpService : HTTPService;
[Test(async)]
public function testExecuteRequestReturnsJSONData() : void {
var expectedData : String = "[\"OK\", \"TIME\", {\"localtime\": [2010, 9, 21, 11, 22, 23, 1, 264, 1], \"asctime\": \"Tue Sep 21 11:22:23 2010\", \"time\": 1285064543.01}]";
mock(httpService).asHTTPService().method("GET").send(hasProperties({command : "time"})).result(expectedData);
var service : DVBIPBridgeService = new DVBIPBridgeService(httpService);
Async.handleEvent(this, service, DVBIPBridgeService.REQUEST_COMPLETE, function(event:Event,data:Object) : void {
var requestData : Object = service.getData();
assertThat(requestData[1], equalTo("TIME"));
assertThat(requestData.localtime.time, equalTo(1285064543.01));
});
service.makeRequest({command : "time"});
}
}
}
So here's a requirement for a matcher, and in the first, would like your feedback.
I often accept Object
as a parameter type when i actually mean IIterable
- However there is no IIterable
interface in as3 that does what i need, which is, require a type that can be iterated over with for each (.. in ...)
A matcher for Iterable that simply caught exceptions on for each (var item:Object in parameterUnderTest)
would be very handy for letting my tests show the real intent, even if my parameter type cant.
eg:
stub(stubTarget).method("addItems").args(Iterable())
I tried to use spy test but I had problems when the test checked how many the methos was executed.
Example:
contextPart = nice(IXMLAContextPart);
_xmlaPart.context = contextPart;
mock(contextPart).getter("nodeDepth").returns(1);
mock(contextPart).method("useRootNode").returns(true);
mock(contextPart).method("template").returns();
mock(contextPart).method("validate").args(anyOf(equalTo("var_1"),equalTo("var_2"))).returns(true);
mock(contextPart).method("validate").args("NO_VALIDATE_AND_DONT_ADD").returns(false);
_xmlaPart.add("var_1", "HOLA");
_xmlaPart.add("var_2", "HOLA2");
var xml:XML = _xmlaPart.generate();
assertThat(contextPart, received().method('template').noArgs().times(1)); //not works. If I use 2 times, the test past... but only once is executed inside generate() funcion
assertThat(contextPart, received().method("useRootNode").noArgs().times(2)); //not works. Same of previous.
assertThat(contextPart, received().method("useRootNode").twice()); //not work
assertThat(contextPart, received().getter("nodeDepth").times(1)); //works fine
assertThat(contextPart, received().method('validate').args(anything()).times(2)); //works fine
generate() function use internaly "nodeDepth", "useRootNode" and "template" once each.
Trying to mock ITransmitter interface, wich is derived from IEventDispatcher and dispatch event. The problem is that event dispatches twice. Here is the example:
var events: Array = new Array();
var t: IEventDispatcher = nice(ITransmitter);
stub(t).asEventDispatcher();
t.addEventListener(UploadEvent.COMPLETE, function(e: UploadEvent): void {
events.push(e);
});
t.dispatchEvent(new UploadEvent(UploadEvent.COMPLETE));
At the end, 'events' array contains 2 objects, but should only one.
In order to work around the brokenness of the flash.utils.describeType()
not reporting final
on method, properties, variables, require the user to explicitly define which namespaces they would like to proxy.
Suggested APIs:
prepareWithNamespaces(ClassToPrepare, [ flash_proxy, mx_internal ]);
[Mock(namespaces="flash.utils.flash_proxy,mx.core.mx_internal")]
public var doodad:ClassToPrepare;
Publish Mockolate ASDocs to http://mockolate.org/
mirror the inline invocations allowed for expect() with the verify() / test spy functionality.
something like:
verify(instance);
spy(instance.method(arg1, argN)).once();
spy(instance.method(spyArg(), spyArg()).once();
Attempting to call a method on the proxy by using Function.apply()
fails as the proxy thinks it is a property invocation not a method invocation. Mockolate should return a function reference for the property getter if a method exists for the same name as the property.
Example use case:
public class LoggerProxy implements ILogger
{
private var _logger:ILogger;
public function set logger(value:ILogger):void
{
_logger = value;
}
public function get debugEnabled():Boolean
{
return _logger ? _logger.debugEnabled : false;
}
public function debug(message:String, ... parameters):void
{
if (debugEnabled)
_logger.debug.apply(_logger, [ message ].concat(parameters));
}
}
Conditional at MockingCouverture#expectationAdded() line 862 is wrong. It should be checking _expectationsAsMocks
.
Workaround, specify .once()
or atLeast(1)
for the expectation.
To aid diagnosis of invocation and expectation errors provide an API to access the invocations that were recorded by a Mockolate instance.
Appears to be a bug in FLoxy.
will not work:
package {
class Anything {
public function invoke(args:Array):void {
}
}
}
[Test(given="with an empty list, a Proxy list, and list is observed",
it="does not call the proxy manager")]
public function it():void {
withAnEmptyList();
withAProxyList();
withListObserved();
verify(proxyList).method(PROXY_LIST_ADD).atMost(NEVER);
verify(proxyList).method(PROXY_LIST_REMOVE).atMost(NEVER);
verify(proxyList).method(PROXY_LIST_RESET).atMost(NEVER);
verify(proxyList).method(PROXY_LIST_DISPOSE).atMost(NEVER);
}
method().never() would be tidier.
Drew
I think I found another possible bug? I am mocking a delegate to return a resultEvent. Inside the code for the Controller, the delegate result returned is correct, but as soon as I exit the controller and come back to the test, the value is not carried through.
This test below fails, with the last Assert returning false, instead of the required true which was set on the mock. When I debug it in the Controller, the value is being set correctly on the model as per the mock, but as soon as I exit the controller, the value is lost.
I tried to catch the ResultEvent.RESULT to see if that is where the value is set, but no luck
Async.handleEvent(this, fixture.eventDispatcher, ResultEvent.RESULT,check,500,null,noEventFired);
Any ideas what I am missing here?
Thanks
Des
Here is an example of it:
{
[Test(async)]
public function checkUsernameTest_user_exists():void
{
// Create the authenticationEvent the Presenter would have sent
authenticationEvent = new AuthenticationEvent(AuthenticationEvent.CHECK_USERNAME);
authenticationEvent.username = testUsername;
var result:Object = true; // User does exist
var token:AsyncToken = new AsyncToken();
var resultEvent:ResultEvent = new ResultEvent(ResultEvent.RESULT, false, false, result, token);
// Mock the delegate to return an AsyncToken
mock(loginDelegateMock).method("checkUsernameExists").args(authenticationEvent.username).returns(token).answers(new ResultAnswer(token, resultEvent));
// Assert that if you receive "false" the USERNAME_EXISTS event is fired
Async.proceedOnEvent(this,fixture.eventDispatcher,AuthenticationEvent.USERNAME_EXISTS,500,noEventFired);
// Make a call to the backend to check if this username exists
fixture.checkUsername(authenticationEvent);
Assert.assertEquals("Assert that the loginModel.usernameExists has changed in Model:", true, fixture.loginModel.usernameExists);
}
}
{
[Mediate(event="AuthenticationEvent.CHECK_USERNAME")]
public function checkUsername(authenticationEvent:AuthenticationEvent):void {
var checkUsernameResultEvent:Function = function (resultEvent:ResultEvent):void
{
// Assign the result to the model
loginModel.usernameExists = resultEvent.result as Boolean;
}
var checkUsernameFaultEvent:Function = function (faultEvent:FaultEvent):void
{
// handle fault
}
executeServiceCall(loginDelegate.checkUsernameExists(authenticationEvent.username),
checkUsernameResultEvent, checkUsernameFaultEvent);
}
}
{
public function checkUsernameExists(username:String):AsyncToken
{
return authenticationService.isValidUser(username);
}
}
{
public class LoginModel{
public var username:String = "";
public var password:String = "";
public var usernameExists:Boolean;
}
}
Drew, this is the error I emailed you about. Creating this so that you can track it publicly. The error in question seems to occur randomly and the test suite is otherwise passing:
ArgumentError: obj cannot be null at org.flemit.reflection::Type$/getType()[/Users/drewbourne/Workspaces/drewbourne/flemit/flemit/src/org/flemit/reflection/Type.as:447] at InterceptorProxyListener()[/Users/drewbourne/Workspaces/drewbourne/floxy/floxy/src/org/floxy/InterceptorProxyListener.as:18] at org.floxy::ProxyRepository/createWithProxyClass()[/Users/drewbourne/Workspaces/drewbourne/floxy/floxy/src/org/floxy/ProxyRepository.as:70] at mockolate.ingredients.floxy::FloxyMockolateFactory/createInstance()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/ingredients/floxy/FloxyMockolateFactory.as:124] at mockolate.ingredients.floxy::FloxyMockolateFactory/prepareInstance()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/ingredients/floxy/FloxyMockolateFactory.as:94] at global/asx.array::forEach()[/Users/drew/Development/workspace-oss-/asx/asx/src/asx/array/forEach.as:12] at mockolate.ingredients.floxy::FloxyMockolateFactory/prepareInstances()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/ingredients/floxy/FloxyMockolateFactory.as:82] at mockolate.ingredients::Mockolatier/prepareInstances()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/ingredients/Mockolatier.as:198] at mockolate.runner.statements::InjectMockInstances/evaluate()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/runner/statements/InjectMockInstances.as:43] at org.flexunit.internals.runners.statements::StatementSequencer/executeStep()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit\internals\runners\statements\StatementSequencer.as:98] at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit\internals\runners\statements\StatementSequencer.as:141] at org.flexunit.token::AsyncTestToken/sendResult()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit\token\AsyncTestToken.as:107] at Function/()[/Users/hobspillane/workday/mockolate/mockolate/src/mockolate/runner/statements/PrepareMockClasses.as:34] at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at Function/http://adobe.com/AS3/2006/builtin::apply() at SetIntervalTimer/onTimer() at flash.utils::Timer/_timerDispatch() at flash.utils::Timer/tick()
For vars marked with [Mock]
if there is a constructorArgs
attribute, try calling resolving and calling a function with the same name on the current test case to get the array of parameters to pass to the constructor.
[Mock(constructorArgs="exampleArgs")]
public var example:Example;
public function exampleArgs():Array { return ["Example", true, 3]; }
MockolateRule required FlexUnit 4.1+, add a mention to the gotchas section and where MockolateRule is first mentioned.
Report on vars
with [Mock]
must be public.
Preparing an empty Array of classes throws an error. Don't do that.
Examples include mocking the Proxy flash_proxy
methods, mx_internal
etc.
Will require changes to FLemit, FLoxy.
I tried to create Mockolate form interface with:
[Rule]
public var mocks:MockolateRule = new MockolateRule();
[Mock]
public var mockIExample:IExample;
but I got this error:
Illegal override of IExample
where IExample
is an interface.
By default make Mockolate log warnings for situations where it cannot create appropriate proxy methods.
For example log warnings for each public var
field in a class when passed to prepare()
.
To save a few imports and make syntax completion a bit nicer, the MockolateRule should provide mock()
, stub()
and verify()
.
[Rule]
public var mocks:MockolateRule = new MockolateRule();
[Mock]
public var flavour:Flavour;
[Test]
public function example():void
{
mocks.mock(flavour).method("combine").args(Flavour).once();
...
mocks.verify(flavour);
}
Drew
Another one for you ;-)
I have a function that loads a local file and then processes is. I want to mock the FileReference browse() and load() functions, so I can test my file logic. Been playing with mocks, but I cannot seem to get what I need to do from the source. The three steps I need to complete are:
Is there a way I can do this?
The function I am trying to mock:
public function addRateSheet():void
{
var loadFile:Function = function(event:Event):void
{
fileReference.load(); // NO NEED TO MOCK THIS FUNCTION, BUT NEED TO CALL THE EVENT ON THE fileReference
};
// Add Event listerners for the upload sequence
fileReference.addEventListener(Event.SELECT, loadFile); // NO NEED TO MOCK THIS
fileReference.addEventListener(Event.COMPLETE, fileLoadCompleteHandler); // NEED TO MOCK THIS EVENT LISTENER
// Open Dialog box and ask user for a file. Only use .txt or .csv files
fileReference.browse([textTypes]); // NO NEED TO MOCK THIS
}
The function under test takes the Event and works on the event.target
public function fileLoadCompleteHandler(event:Event):void
{
var currentFileReference:FileReference = FileReference(event.target);
}
}
As usual would appreciate your help on this.
Thanks
Des
Compile and package a zip with source, SWC, ASDocs and publish to github downloads.
A Partial Mock Object should by default call the super method or property unless an Expectation has been defined.
I'm trying to mock a RemoteObject:
service = strict(RemoteObject);
stub(service).method("getOperation").args(anything()).returns(null);
var x:* = service.getOperation("asdf");
But, on the last line (var x:* = service.getOperation(...)
), I get this error:
... snip ...
at tests.global.services::TestService/testRealCallWithError()[.../services/TestService.as:122]
at asmock.generated::RemoteObject4570E96E984C736EA25B72EBC1E9FFEF3CE48081/getOperation()
at org.floxy::InterceptorProxyListener/methodExecuted()[.../floxy/InterceptorProxyListener.as:34]
at org.flemit.reflection::Type$/getType()[.../reflection/Type.as:458]
at global/flash.utils::getDefinitionByName()
ReferenceError: Error \#1065: Variable RemoteObject4570E96E984C736EA25B72EBC1E9FFEF3CE48081 is not defined.
I am (I believe) correctly preparing RemoteObject
(using prepare(RemoteObject)
in conjunction with Async.proceedOnEvent
).
Is this a known error? Is there anything I can do about it?
Thanks,
David
Just upgraded to 0.12.2. I'm getting an odd error on just a couple of our existing test cases. We're preparing the mocks for this particular strict the same way we are with others. Haven't been able to find anything that makes this case unique yet.
Error
at mockolate.ingredients::InstanceRecipeBuilder/withClassRecipe(InstanceRecipeBuilder.as:21)
at mockolate.ingredients::Mockolatier/strict(Mockolatier.as:172)
at global/mockolate::strict(strict.as:28)
at com.workday.ui.flex.view.controls.workFeedClasses::WorkFeedFilterMenuPresenterTest/setup(WorkFeedFilterMenuPresenterTest.as:54)
at Function/http://adobe.com/AS3/2006/builtin::apply
at flex.lang.reflect::Method/apply(Method.as:244)
at org.flexunit.runners.model::FrameworkMethod/invokeExplosively(FrameworkMethod.as:201)
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate(InvokeMethod.as:72)
at org.flexunit.internals.runners.statements::SequencerWithDecoration/executeStep(SequencerWithDecoration.as:100)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:141)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:107)
at org.flexunit.internals.runners.statements::ExpectAsync/sendComplete(ExpectAsync.as:560)
at org.flexunit.internals.runners.statements::ExpectAsync/handleAsyncEventFired(ExpectAsync.as:431)
at flash.events::EventDispatcher/dispatchEventFunction
at flash.events::EventDispatcher/dispatchEvent
at org.flexunit.async::AsyncHandler/handleEvent(AsyncHandler.as:156)
at flash.events::EventDispatcher/dispatchEventFunction
at flash.events::EventDispatcher/dispatchEvent
at Function/http://adobe.com/AS3/2006/builtin::apply
at SetIntervalTimer/onTimer
at flash.utils::Timer/_timerDispatch
at flash.utils::Timer/tick
Drew
Is there a way to mock out a Singleton instance? I have the following pretty stock Flex URLParser and need to test the logic of parsing the URL.
public class MainPresenter
{
public var browserManager:IBrowserManager;
public function setIntialView():void
{
browserManager = BrowserManager.getInstance();
browserManager.init();
var object:Object = URLUtil.stringToObject(browserManager.fragment,"&");
}
Problem I hit is at the "getInstance" line, a new browserManager is set and the mock I do is cleared. I do not know if it is possible to mock static classes, specifically the BrowserManager & URLUtil classes. If I can mock them, then I can control the result.
Thanks
Des
Heres the contents of my test:
stub(loginDelegate).method("login").args( array("username", "password") );
mock(loginDelegate).method("login").args( array("username", "password") ).twice();
loginDelegate.login("username", "password");
loginCommand.execute("UserName", "PassWord");
verify(loginDelegate);
I have a breakpoint within the loginDelegate.login() method ad it fires twice in this case. After stubbing the method I'm expecting it to not fire at all.
Check the constructor signatures with the MockolateRunner parent class, possible mismatch causing runtime errors when linking against the FU4.1 and Mockolate SWCs.
should be similar to the failure messages for received()
, eg:
Error: No Expectations defined for GeoModel(model).getCountryRegions([Country code="NN" name="Never Never Land"], [object Responder])
currently:
Error: No Expectation defined for Invocation:[FloxyInvocation invocationType=METHOD name="getCountryRegions" arguments=[[Country code="NN" name="Never Never Land"], [object Responder]]]
Add a section to the stubbing and mocking page about using Hamcrest matchers and how they interact with the Invocation for matching the arguments.
Include examples of invocations that will and won't match.
I my test i'm preparing mock of subclass of spark.components.Window, like this:
[Before(async, timeout=6000, order=1)]
public function prepareMockolates():void {
// SplashWindow is mxml component based on spark.components.Window
Async.proceedOnEvent(this, prepare(SplashWindow), Event.COMPLETE);
}
[Before(order=2)]
public function setUp():void {
...
view = nice( SplashWindow );
...
}
After update to version 0.11.0 test failed with this error:
VerifyError: Error #1053: Illegal override of mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::$removeChild() in asmock.generated.SplashWindow10E410F4882BDD7AD3A3288A2E60E403F04302CC.
at flash.system::ApplicationDomain/getDefinition()
at Function/org.floxy:ProxyRepository/org.floxy:IProxyRepository:prepare/org.floxy:swfLoadedHandler()[/Users/drew/Development/workspace-burrito/floxy/floxy/src/org/floxy/ProxyRepository.as:184]
I'm using flex sdk 4.1 and flexunit 4.1. With mockolate v0.10.0 this error didn't show up.
Something like:
mocks.addConstructorOverrideFor(NetStream, function(netStreamClass:Class, constructorArgs:Array):NetStream {
var netConnection:NetConnection = new NetConnection();
netConnection.connect(null);
return new netStreamClass(netConnection)
});
Drew
Thought I'd try this approach to log our conversations. I tried the new notation you presented around the runner, but I must be doing something wrong?
import mockolate.*;
import mockolate.ingredients.answers.*;
import mockolate.prepare;
public class LoginPresentorTests
{
// SUT
private var loginPresentor:LoginPresentor;
// Mock for the Model within LoginPresentor
private var loginModelMock:LoginModel;
[Before(order=1, async, timeout=5000)]
public function prepareMockolates():void
{
Async.proceedOnEvent(this, prepare(LoginModel), Event.COMPLETE);
}
[Before(order=2)]
public function runBeforeEveryTest():void
{
loginPresentor = new LoginPresentor();
// Event within the test and not on the LoginPresentor
}
[Test(async)]
public function testLogin():void
{
// Mock the dependent classes
loginModelMock = strict(LoginModel);
// Stub
// No current behavior to mock
// Assign the mock to the LoginPresentor
loginPresentor.loginModel = loginModelMock;
Assert.assertNotNull("LoginModel Mock available", loginModelMock);
}
import mockolate.runner.MockolateRunner; MockolateRunner;
import org.flexunit.async.Async;
[RunWith("mockolate.runner.MockolateRunner")]
public class LoginPresentorTests
{
// SUT
private var loginPresentor:LoginPresentor;
[Mock(type="strict")]
private var loginModelMock:LoginModel;
[Before]
public function runBeforeEveryTest():void
{
loginPresentor = new LoginPresentor();
}
[Test(async)]
public function testLogin():void
{
// No current behaviour to mock
// Assign the mock to the LoginPresentor
loginPresentor.loginModel = loginModelMock;
Assert.assertNotNull("LoginModel Mock available", loginModelMock);
}
Fails with assert not null. This is the fail stacktrace
LoginModel Mock available - object was null: null
at flexunit.framework::Assert$/failWithUserMessage(Assert.as:591)
at flexunit.framework::Assert$/failNull(Assert.as:533)
at flexunit.framework::Assert$/assertNotNull(Assert.as:311)
**[ at com.wl.sfx.unit.presentor::LoginPresentorTests/testLogin(LoginPresentorTests.as:81) ]
at Function/http://adobe.com/AS3/2006/builtin::apply
at flex.lang.reflect::Method/apply(Method.as:208)
at ReflectiveCallable/run(FrameworkMethod.as:297)
at org.flexunit.runners.model::FrameworkMethod/applyExplosivelyAsync(FrameworkMethod.as:171)
at org.flexunit.runners.model::FrameworkMethod/invokeExplosivelyAsync(FrameworkMethod.as:186)
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate(InvokeMethod.as:77)
at org.flexunit.internals.runners.statements::ExpectAsync/evaluate(ExpectAsync.as:544)
at org.flexunit.internals.runners.statements::StackAndFrameManagement/evaluate(StackAndFrameManagement.as:129)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.internals.runners.statements::AsyncStatementBase/sendComplete(AsyncStatementBase.as:76)
at org.flexunit.internals.runners.statements::StatementSequencer/sendComplete(StatementSequencer.as:165)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:138)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.internals.runners.statements::InvokeMethod/handleMethodExecuteComplete(InvokeMethod.as:89)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.runners.model::FrameworkMethod/applyExplosivelyAsync(FrameworkMethod.as:173)
at org.flexunit.runners.model::FrameworkMethod/invokeExplosivelyAsync(FrameworkMethod.as:186)
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate(InvokeMethod.as:77)
at org.flexunit.internals.runners.statements::SequencerWithDecoration/executeStep(SequencerWithDecoration.as:104)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.internals.runners.statements::StatementSequencer/evaluate(StatementSequencer.as:108)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at mockolate.runner::Inject/evaluate(Inject.as:35)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.internals.runners.statements::StatementSequencer/evaluate(StatementSequencer.as:108)
at org.flexunit.runners::BlockFlexUnit4ClassRunner/runChild(BlockFlexUnit4ClassRunner.as:130)
at org.flexunit.internals.runners::ChildRunnerSequencer/executeStep(ChildRunnerSequencer.as:82)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.internals.runners.statements::StatementSequencer/evaluate(StatementSequencer.as:108)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.internals.runners.statements::AsyncStatementBase/sendComplete(AsyncStatementBase.as:76)
at org.flexunit.internals.runners.statements::StatementSequencer/sendComplete(StatementSequencer.as:165)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:138)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.internals.runners.statements::AsyncStatementBase/sendComplete(AsyncStatementBase.as:76)
at org.flexunit.internals.runners.statements::StatementSequencer/sendComplete(StatementSequencer.as:165)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:138)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.internals.runners.statements::InvokeMethod/handleMethodExecuteComplete(InvokeMethod.as:89)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at org.flexunit.runners.model::FrameworkMethod/applyExplosivelyAsync(FrameworkMethod.as:173)
at org.flexunit.runners.model::FrameworkMethod/invokeExplosivelyAsync(FrameworkMethod.as:186)
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate(InvokeMethod.as:77)
at org.flexunit.internals.runners.statements::SequencerWithDecoration/executeStep(SequencerWithDecoration.as:104)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.internals.runners.statements::StatementSequencer/evaluate(StatementSequencer.as:108)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.token::AsyncTestToken/sendResult(AsyncTestToken.as:118)
at mockolate.runner::Prepare/evaluate(Prepare.as:31)
at org.flexunit.internals.runners.statements::StatementSequencer/executeStep(StatementSequencer.as:97)
at org.flexunit.internals.runners.statements::StatementSequencer/handleChildExecuteComplete(StatementSequencer.as:134)
at org.flexunit.internals.runners.statements::StatementSequencer/evaluate(StatementSequencer.as:108)
Thanks
Des
I just started using mockolate yesterday, and I'm enjoying the experience ;)
I noticed something though. I had a test that was making a nice mockolate out of a spark.components.Form. I was testing a function that takes a Form parameter and dynamically adds some FormItem objects to it. The test worked fine (FlexUnit4.1), although was very slow. However, if I ran the test runner while connecting to the FB code coverage plugin, the tests hang and never finish.
I'll switch to using an interface or something, but wanted to mention it. I can provide more details if it isn't easily reproducible.
Thanks for the great product!
I am looking for the Easymock style capture where I can get access to the param and do any inspections to it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.