Mockito problems - Please make sure you specified a call to stub in given Options

111 views
Skip to first unread message

Eric H

unread,
Nov 11, 2011, 2:42:06 PM11/11/11
to mockito-flex
Hello,
I'm trying to get a handle on mocking w/ Mockito to and I keeping
getting this error:
"Please make sure you specified a call to stub in given". Also, I
cannot get mockito to work unless I add the mock directive
outside the class:
[code]
[Mock(type="common.services.ScaleService")]
[/code]
Here's a copy of my code:
[code]
package TDMSETestSuites.organWeights.tests
{
import common.interfaces.IScaleService;
import common.services.ScaleService;
import flash.events.EventDispatcher;
import flash.utils.Timer;
import flexunit.framework.Assert;
import mx.collections.ArrayCollection;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.remoting.test.RemoteObjectStub;
import org.flexunit.async.Async;
import org.flexunit.async.TestResponder;
import org.flexunit.rules.IMethodRule;
import org.hamcrest.core.*;
import org.mockito.Mockito;
import org.mockito.integrations.*;
import org.mockito.integrations.flexunit4.MockitoRule;
import org.spicefactory.parsley.core.context.Context;
import org.spicefactory.parsley.dsl.context.ContextBuilder;
import org.spicefactory.parsley.flex.FlexConfig;
//so far, this, declaration, at this level is the only way it
works-
WHY??
[Mock(type="common.services.ScaleService")]
public class ScaleServiceTest extends TDMSETestBase
{
[Rule]
public var mockitoRule:IMethodRule = new
MockitoRule();//mockito
crucial
[Inject(id="roScale")]
public var injectedScaleRemoteObject:RemoteObject;
[Inject]
public var injectedScaleService:IScaleService;
[Inject]
public var iScaleService:IScaleService;
public var scaleService:ScaleService;
//---- mockito properties
--------------------------------
//--------------------------------------------------------
private var mockScaleService:ScaleService;
private var mockScaleIService:IScaleService;
private var mockito:Mockito = new Mockito();
public var context:Context;
private var fault:Boolean=Boolean(false);
private var resultCheckTimer:Timer;
// The timer and result check timeouts
private static const TIMEOUT_MS:int = 4000;
private static const RESULT_CHECK_TIMEOUT_MS:int =
3500;
[Before]
public function setUp():void
{
//create base TDMSE parsley context
context = ContextBuilder.newBuilder()
.config(FlexConfig.forClass(TDMSEAppParsleyConfig))
.object(this)
.build
scaleService = new ScaleService();
mockScaleService = mock(ScaleService);
}
//---- MOCHITO TESTS
------------------------------------------------------------
//-------------------------------------------------------------------------
------
[Test(async)]
public function mockitoGetScaleData1():void
{
var token:AsyncToken =
mockScaleService.getScaleData(faultHandler);

mockito.given(mockScaleService.getScaleData).willReturn(token);

mockito.verify().that(mockScaleService.getScaleData(faultHandler));
}
//-------------------------------------------------------------------------
-----
}
}

[/code]
here's the service class and method it's testing:
[code]
public class ScaleService extends EventDispatcher implements
IScaleService
{
[Inject(id="roScale")]
public var scaleService:RemoteObject;
public function
getScaleData(getScaleDataFaultHandler:Function):AsyncToken
{
return
scaleService.getScaleData().addResponder(new
AsyncResponder(getScaleData_result, getScaleDataFaultHandler));
}
}
[/code]
I'm completely stumped here and have been googling for days!!
-E

Kris

unread,
Nov 13, 2011, 5:31:42 AM11/13/11
to mockit...@googlegroups.com
I think the main reason is that you instantiate mockito on your own. I'm not sure where did you find it however that's not the right way. MockitoRule creates Mockito instance in a global context and later on global functions expose mockito functionality for you.

1) Remove your manual instancing of Mockito 
2) Use global functions in your test

 [Test(async)]
               public function mockitoGetScaleData1():void
               {
                       var token:AsyncToken =
mockScaleService.getScaleData(faultHandler);

/*mockito.*/given(mockScaleService.getScaleData).willReturn(token);

/*mockito.*/verify().that(mockScaleService.getScaleData(faultHandler));
               }

3) Also I'm not sure if you got the concepts right. In above test you define a stub to later on verify a call that isn't happening anywhere. Mockito - unlike record/playback frameworks lets you verify only interesting parts. The verification allows you to check number of invocations of the certain function with certain arguments. I assume you want to make sure your delegate service get's properly called.
A sample test would look like

{
    // given
    var mockDelegate:IService = mock(IService);
    var classUnderTest:Service = new Service(mockDelegate);

    // when
    classUnderTest.service("some argument"); // call your system
    // then

   verify().that(mockDelegate.service(any()); // now check that the delegate got called
}

In a scenario where you want to stub the delegate you do:

    // given
    var mockAsyncToken:AsyncToken = mock(AsyncToken);
    var mockDelegate:IService = mock(IService);
    var classUnderTest:Service = new Service(mockDelegate);
    given(mockDelegate.service(any())).willReturn();

    // when
    var token:AsyncToken = classUnderTest.service("some argument"); 
    // then
    assertTrue(mockAsyncToken === token); // here you can confirm a stub returned what you expected

}

interface IService
{
   function someService(arg:String):AsyncToken;
}

class Service implements IService
{
    private var delegate:IService;

    public Service(delegate:IService)
    {
        this.delegate = delegate;
    }

    public function someService(arg:String):AsyncToken
    {
        return delegate.someService(arg);
    }
}


For interactions that are possible on stubs take a look here: https://bitbucket.org/loomis/mockito-flex/wiki/Home. A sample is in the news section for the 1.4 milestone.

Regards,
Kris

Eric H

unread,
Nov 15, 2011, 4:12:44 PM11/15/11
to mockito-flex
Just as a quick test, I ran this:

[code]
[Test(async)]
public function mockitoGetScaleData1():void
{
var token:AsyncToken =
mockScaleService.getScaleData(faultHandler);
given(mockScaleService.getScaleData).willReturn(token);
verify().that(mockScaleService.getScaleData(faultHandler));
}
[/code]

now, I'm getting this strange error:

Wanted but not invoked at all:
asmock.generated:ScaleService1AE3AC235EF53AA8E4B380A35FE059AE3A7C8446/
getScaleData(function Function() {}).
Here's my latest code:

[code]
package TDMSETestSuites.organWeights.tests
{
import TDMSETestSuites.common.TDMSETestBase;
import TDMSETestSuites.organWeights.mocks.IScaleServiceMock;

import common.interfaces.IScaleService;
import common.services.ScaleService;

import flash.events.EventDispatcher;
import flash.utils.Timer;

import flexunit.framework.Assert;

import mx.collections.ArrayCollection;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.remoting.test.RemoteObjectStub;

import org.flexunit.async.Async;
import org.flexunit.async.TestResponder;
import org.flexunit.rules.IMethodRule;
import org.mockito.integrations.*;
import org.mockito.integrations.flexunit4.MockitoRule;

//so far, this, declaration, at this level is the only way it works-
WHY??
[Mock(type="common.services.ScaleService")]

public class ScaleServiceTest extends TDMSETestBase
{
[Rule]
public var mockitoRule:IMethodRule = new MockitoRule();//mockito
crucial

private var mockScaleService:ScaleService;

private var remoteObjectStub:RemoteObjectStub; //stub for
RemoteObject dependency in controller
private var fault:Boolean=Boolean(false);

public function ScaleServiceTest(){}

override public function setUp():void
{
super.setUp();
remoteObjectStub = new RemoteObjectStub("roScale");
remoteObjectStub.delay = 500;
mockScaleService = mock(ScaleService);
mockIScaleService = mock(IScaleService);
}

[After]
public function tearDown():void{}

[Test(async)]
public function mockitoGetScaleData1():void
{
var token:AsyncToken =
mockScaleService.getScaleData(faultHandler);
given(mockScaleService.getScaleData).willReturn(token);
verify().that(mockScaleService.getScaleData(faultHandler));
}
}
}
[/code]


Thanks so much for your help!

Kris

unread,
Nov 16, 2011, 6:48:59 AM11/16/11
to mockit...@googlegroups.com
Once again, what you show in your test is hard to follow. 

With mockito you work this way:

1) setup mock dependencies for your system under test (I can't see any system under test in your code, I can see a bunch of mocked dependencies though)
2) if it's needed setup stubs (given()....)
3) call system under test (again in your code I can only see calling the mock getScaleData)
4) at the end of the test you verify certain interactions which you expect to have happened while calling the system under test

See what happens if you do just this:

               [Test(async)]
               public function mockitoGetScaleData1():void
               {
                       var token:AsyncToken = mockScaleService.getScaleData(faultHandler);
                       verify().that(mockScaleService.getScaleData(faultHandler));
               }

Regards,
Kris

Eric H

unread,
Nov 18, 2011, 1:11:30 PM11/18/11
to mockito-flex
Sorry for the long reply. I guess one thing that I'm not getting is
what you mean by system under test. In this case, I am assuming the
ScaleService but I wanted to clarify that.

Also, I tried your suggestion and the test works fine:

[Test(async)]
public function mockitoGetScaleData1():void
{
var token:AsyncToken = mockScaleService.getScaleData(faultHandler);
verify().that(mockScaleService.getScaleData(faultHandler));
}

it's just when I add the given stub, it craps out with this full
stacktrace:


at org.mockito.impl::Times/verify()[C:\dev\mockito-flex\mockito\src
\main\flex\org\mockito\impl\Times.as:51]
at org.mockito.impl::MockInterceptorImpl/methodCalled()[C:\dev\mockito-
flex\mockito\src\main\flex\org\mockito\impl\MockInterceptorImpl.as:61]
at org.mockito.impl::AsmockMockery/methodCall()[C:\dev\mockito-flex
\mockito\src\main\flex\org\mockito\impl\AsmockMockery.as:103]
at asmock.framework::ASMockInterceptor/intercept()
at InterceptorProxyListener/methodExecuted()[/Users/drew/Development/
workspace-burrito/floxy/floxy/src/org/floxy/
InterceptorProxyListener.as:61]
at
mockolate.generated::ScaleService71C1DE3337FE38E7A29B098856BB7A2F68D22188/
getScaleData()
at commonTest.services::ScaleServiceTest/mockitoGetScaleData1()[C:
\TDMSE_2_6\tdmse\flex-test\commonTest\services\ScaleServiceTest.as:82]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at flex.lang.reflect::Method/apply()[E:\hudson\jobs\FlexUnit4-
Flex4.1\workspace\FlexUnit4\src\flex\lang\reflect\Method.as:244]
at org.flexunit.runners.model::FrameworkMethod/invokeExplosively()[E:
\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit
\runners\model\FrameworkMethod.as:201]
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate()
[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit
\internals\runners\statements\InvokeMethod.as:72]
at org.flexunit.internals.runners.statements::ExpectAsync/evaluate()[E:
\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit
\internals\runners\statements\ExpectAsync.as:595]
at org.flexunit.internals.runners.statements::RunBeforesInline/
handleSequenceExecuteComplete()[E:\hudson\jobs\FlexUnit4-
Flex4.1\workspace\FlexUnit4\src\org\flexunit\internals\runners
\statements\RunBeforesInline.as:112]
at org.flexunit.token::AsyncTestToken/sendResult()[E:\hudson\jobs
\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit\token
\AsyncTestToken.as:107]
at org.flexunit.internals.runners.statements::AsyncStatementBase/
sendComplete()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src
\org\flexunit\internals\runners\statements\AsyncStatementBase.as:76]
at org.flexunit.internals.runners.statements::StatementSequencer/
sendComplete()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src
\org\flexunit\internals\runners\statements\StatementSequencer.as:172]
at org.flexunit.internals.runners.statements::StatementSequencer/
handleChildExecuteComplete()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace
\FlexUnit4\src\org\flexunit\internals\runners\statements
\StatementSequencer.as:145]
at org.flexunit.token::AsyncTestToken/sendResult()[E:\hudson\jobs
\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit\token
\AsyncTestToken.as:107]
at org.flexunit.internals.runners.statements::InvokeMethod/evaluate()
[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org\flexunit
\internals\runners\statements\InvokeMethod.as:73]
at org.flexunit.internals.runners.statements::SequencerWithDecoration/
executeStep()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src
\org\flexunit\internals\runners\statements\SequencerWithDecoration.as:
100]
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.internals.runners.statements::StatementSequencer/
evaluate()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org
\flexunit\internals\runners\statements\StatementSequencer.as:109]
at org.flexunit.internals.runners.statements::RunBeforesInline/
evaluate()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org
\flexunit\internals\runners\statements\RunBeforesInline.as:97]
at org.flexunit.internals.runners.statements::RunAftersInline/
evaluate()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org
\flexunit\internals\runners\statements\RunAftersInline.as:104]
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 org.mockito.integrations.flexunit4::AssignMocks/assignMocks()[C:\dev
\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\AssignMocks.as:45]
at org.mockito.integrations.flexunit4::AssignMocks/evaluate()[C:\dev
\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\AssignMocks.as:25]
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/org.mockito.integrations.flexunit4:PrepareMocks/
private:prepareMocks/
org.mockito.integrations.flexunit4:repositoryPreparedHandler()[C:\dev
\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\PrepareMocks.as:44]
at Function/<anonymous>()[C:\dev\mockito-flex\mockito\src\main\flex\org
\mockito\impl\AsmockMockery.as:81]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at CompletedEventDispatcher/addEventListener()[/Users/drew/Development/
workspace-burrito/floxy/floxy/src/org/floxy/ProxyRepository.as:521]
at org.mockito.impl::AsmockMockery/prepareClasses()[C:\dev\mockito-flex
\mockito\src\main\flex\org\mockito\impl\AsmockMockery.as:88]
at org.mockito::Mockito/prepareClasses()[C:\dev\mockito-flex\mockito
\src\main\flex\org\mockito\Mockito.as:238]
at org.mockito.integrations.flexunit4::PrepareMocks/prepareMocks()[C:
\dev\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\PrepareMocks.as:40]
at org.mockito.integrations.flexunit4::PrepareMocks/evaluate()[C:\dev
\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\PrepareMocks.as:23]
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.internals.runners.statements::StatementSequencer/
evaluate()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace\FlexUnit4\src\org
\flexunit\internals\runners\statements\StatementSequencer.as:109]
at org.flexunit.internals.runners.statements::MethodRuleBase/
proceedToNextStatement()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace
\FlexUnit4\src\org\flexunit\internals\runners\statements
\MethodRuleBase.as:77]
at org.mockito.integrations.flexunit4::MockitoRule/evaluate()[C:\dev
\mockito-flex\mockito\src\main\flex\org\mockito\integrations
\flexunit4\MockitoRule.as:50]
at org.flexunit.internals.runners.statements::StackAndFrameManagement/
handleTimerComplete()[E:\hudson\jobs\FlexUnit4-Flex4.1\workspace
\FlexUnit4\src\org\flexunit\internals\runners\statements
\StackAndFrameManagement.as:138]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.utils::Timer/tick()


On Nov 16, 6:48 am, Kris <kris.karczmarc...@gmail.com> wrote:
> Once again, what you show in your test is hard to follow.
>
> With mockito you work this way:
>
> 1) setup mock *dependencies* for your* system under test* (I can't see any
> system under test in your code, I can see a bunch of mocked dependencies
> though)
> 2) if it's needed setup stubs (given()....)
> 3) call *system under test* (again in your code I can only see calling the
> mock getScaleData)
> 4) at the end of the test you verify certain interactions which you expect
> to have happened while calling the *system under test*

Kris

unread,
Nov 18, 2011, 2:08:26 PM11/18/11
to mockit...@googlegroups.com
OK :) let me get you through some basics.

Why do you need mocking? You want to test A but it's hard since it depends on B which depends on C etc. What do you do? You mock B. B is your dependency while A is your system under test. 

Using mockito you want to do what is needed by the test of A and then make sure all the calls to B happened as you expected using verify() syntax. Another scenario is that in order to successfully test A some kind of predictable response is needed from B. That's where you use stubs. So, before making any calls to A you instruct B to behave the way you want with the given() syntax.

What confused me in your test is:

  • mockScaleService is equivalent to B from above description you call it in the first place 
  • right after it you specify a stub to return something when given certain argument
  • then you expect mockito to verify calls to mockScaleService
Bizarre :)

Tell me what you think,
Kris


Reply all
Reply to author
Forward
0 new messages