infinite / mockito-flex

0 stars 0 forks source link

Answer object should be able to get access to all arguments #32

Open infinite opened 10 years ago

infinite commented 10 years ago

Hi,

It would be nice if the Answer object would have the opportunity to get access too all the arguments passed to that subbed method before retrieving an answer.

infinite commented 10 years ago

From Anonymous on 2011-02-23 13:34:11+00:00

Example in Java:

{{{

!java

when(mock.someMethod(anyString())).thenAnswer(new Answer() { Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); Object mock = invocation.getMock(); return "called with arguments: " + args; } }); }}}

infinite commented 10 years ago

From loomis on 2011-02-23 22:16:12+00:00

It is possible to access all the arguments by creating and Answer that also implements StubbingContextAware. All Answers implementing StubbingContextAware are given a StubbingContext that has all the args before invoking answer() method. Not as straight forward as the proposal but was there for quite a while. Take a look at the CallOriginal source code. It uses StubbingContext for other purposes but the concept is the same. Also there is an API that allows defining actions on stub args. Please review the news section for the details. If any of the options work for you please let me know and I'll close the issue.

Regards, Kris

infinite commented 10 years ago

From Anonymous on 2011-02-24 11:04:56+00:00

Hi,

many thanks for your quick reply! The solution with the StubbingContextAware is my preferred one. I created a class that delegates the complete answer of the subbed method to my own in my test, so that I have a simple way of accessing the arguments and defining my answer.

{{{

!java

public class DelegateAnswerTo implements Answer, StubbingContextAware {

private var context:StubbingContext;
/**
 * Delegates the answer to a given callback. Whenever the stubbed
 * function is called, the call will be delegated to this callback, and the
 * original arguments will be passed.
 */
private var delegateCallback:Function;

public function DelegateAnswerTo(callback:Function)
{
    delegateCallback = callback;
}

public function useContext(stubbingContext:StubbingContext):void
{
    context = stubbingContext;
}

public function give():*
{
    return delegateCallback.apply(null, context.args);
}

} }}}

Then I created a convenience method that is easier to use in the tests:

{{{

!java

public function delegateAnswerTo(delegateFunction:Function):Answer { return new DelegateAnswerTo(delegateFunction); } }}}

Finally the usage looks something like this:

{{{

!java

var answer:Function = function(a:int, b:int):int { return 10 + a + b; } given(mockCalculator.add(any(), any())).will(delegateAnswerTo(answer)); }}}

If you want, it would be nice to have something like this directly in mockito, to make thinks a bit easier...

Best regards,

Johanna

infinite commented 10 years ago

From Anonymous on 2011-03-01 17:47:52+00:00

@Anon / Johanna

Awesome - thanks for this! I just used it perfectly on my project.

Thanks for sharing.

infinite commented 10 years ago

From arieljake on 2011-05-26 23:29:01+00:00

Thank you for this, very useful!!