Open GoogleCodeExporter opened 8 years ago
That seems like a nice feature actually. Are you interested in helping out and
provide patch for this is would be really great!
Original comment by johan.ha...@gmail.com
on 6 Nov 2012 at 5:42
Hi Johan,
I am working on that, I will keep you updated as soon as I can :)
Regards,
Mohamed
Original comment by ayman92...@gmail.com
on 7 Nov 2012 at 9:35
Have you made any progress? Please just ask if you have any questions. I
suppose that it can be a bit tricky to get into.
Original comment by johan.ha...@gmail.com
on 29 Nov 2012 at 6:51
Sorry for the delay.
In fact, in mockito, an invocation has necessarely a signature and arguments
Without these informations, I am unable to find in the mockrepository the
instance I am looking for.
So I was trying to mock the first constructor of the class and store somewhere
it's arguments, what do you think ?
Regards
Original comment by mohamed....@gmail.com
on 1 Dec 2012 at 12:50
I just got another idea, maybe it would work if we did something like this:
whenNew(A.class).withAnyArguments().thenReturn(mockedObject)
When "withAnyArguments" is invoked it will iterate over ALL constructors of A
(I think Whitebox has some methods to help out with this) and for each
constructor extract it's parameter types and store it in a hashmap (constructor
-> param types) or something. Then for each constructor in the hashmap invoke:
whenNew(<constructor in hashmap>).withArguments(any(constructorParamType1) ,
any(constructorParamType2), .., any(constructorParamTypeN));
(Actually whenNew shouldn't be used since directly since we'll then end up with
a cyclic package dependency, rather use something like "new
ConstructorAwareExpectationSetup" instead).
This way we don't need to keep any additional state in the mock repository and
we'll leverage on Mockito for flexible argument matching. Do you think this
will work?
Original comment by johan.ha...@gmail.com
on 2 Dec 2012 at 8:32
I've actually tried to implement this myself. I made only two new tests in
"samples.powermockito.junit4.whennew.WhenNewTest" (the two last ones). I think
it works but it's not tested well enough. Please try it out and see if it works
and pretty please help out and write some more automated tests :)
Original comment by johan.ha...@gmail.com
on 2 Dec 2012 at 2:24
Awsome :)
I was working on that today, it is pretty similar to what I was doing :
private static <T> OngoingStubbing<T> createNewSubsituteMock(Class<T> type)
throws Exception {
if (type == null) {
throw new IllegalArgumentException("type cannot be null");
}
final Class<T> unmockedType = (Class<T>) WhiteboxImpl
.getUnmockedType(type);
/*
* Check if this type has been mocked before
*/
NewInvocationControl<OngoingStubbing<T>> newInvocationControl = (NewInvocationControl<OngoingStubbing<T>>) MockRepository
.getNewInstanceControl(unmockedType);
if (newInvocationControl == null) {
InvocationSubstitute<T> mock = MockCreator.mock(
InvocationSubstitute.class, false, false, null, null,
(Method[]) null);
newInvocationControl = new MockitoNewInvocationControl(mock);
MockRepository.putNewInstanceControl(type, newInvocationControl);
MockRepository
.addObjectsToAutomaticallyReplayAndVerify(WhiteboxImpl
.getUnmockedType(type));
}
OngoingStubbing<T> expectSubstitutionLogic = null;
Constructor<?>[] allConstructors = WhiteboxImpl
.getAllConstructors(unmockedType);
for (Constructor<?> constructor : allConstructors) {
List<Object> arguments = new ArrayList<Object>();
Class<?>[] parameterTypes = constructor.getParameterTypes();
for (Class<?> clazz : parameterTypes) {
arguments.add(Mockito.any(clazz));
}
expectSubstitutionLogic = newInvocationControl.expectSubstitutionLogic(arguments);
}
return expectSubstitutionLogic;
}
Original comment by mohamed....@gmail.com
on 2 Dec 2012 at 3:02
I had some problems with it, I will take a look to
DelegatingToConstructorsOngoingStubbing.
I will an svn update and make some tests to see if it works fine.
By the way, what about the same feature for methods as well ?
Something like :
when(mockedObject.foo(withAnyArguments()) or
when(mockedObject).foo(withAnyArguments()) ?
Regards,
Original comment by mohamed....@gmail.com
on 2 Dec 2012 at 3:07
Great, tell me if it works for you when you've tried it.
I suspect that the code you wrote don't work because if
"newInvocationControl.expectSubstitutionLogic(arguments)" is called twice
mockito will think that we're in the wrong state. Since what that code is
actually doing is something similar to:
when(x.y());
when(x.z());
I.e. there's "thenReturn" before when(x.z());
For methods this already exists. You can use the "stubbing API" (you don't need
mocks for this), e.g.
stub(method(X.class, "methodName").toReturn(someObject);
You can also replace and suppress methods etc (see
org.powermock.api.support.membermodification.MemberModifier).
Original comment by johan.ha...@gmail.com
on 2 Dec 2012 at 6:01
It works fine for me :)
The only things with :
stub(method(X.class, "methodName").toReturn(someObject);
is that :
- It is not easy to read
- Need to add the class in the PrepareForTest annotation
- Possible mistake in the name of the method as it is a string
Perhaps, it should be in Mockito at the first place
Original comment by mohamed....@gmail.com
on 2 Dec 2012 at 6:31
Great :)
If I would have designed that API today it would look different :).
But without breaking the existing API it would be possible to do something like
this (but it won't work right now):
stub(methodIn(X.class).methodToStub()).toReturn(x);
We're using something similar in the Awaitility project.
How ever I don't think either
when(mockedObject.foo(withAnyArguments())
nor
when(mockedObject).foo(withAnyArguments())
will work since you only provide ONE argument matcher. What if foo has two
parameters? You can't invoke with only one parameter (withAnyArguments()).
Mockito already has support for this in the sense that you can do:
when(mockedObject.foo(any())
Original comment by johan.ha...@gmail.com
on 2 Dec 2012 at 6:42
If we have a class A that contains an overloaded method foo :
String foo(B1 b1)
String foo(B1 b1, B2 b2)
String foo(B1 b1, B2 b2, B3 b3)
....
when(mockedObject.foo(withAnyArguments()).thenReturn("Hello World");
should be equivalent to :
when(mockedObject.foo(any(B1)).thenReturn("Hello World");
when(mockedObject.foo(any(B1), any(B2)).thenReturn("Hello World");
when(mockedObject.foo(any(B1), any(B2), any(B3)).thenReturn("Hello World");
...
So basically, the idea is to get the list of all the method with same name,
then for each, we call the previous instruction.
But I think this should be implemented in Mockito side.
Original comment by mohamed....@gmail.com
on 4 Dec 2012 at 10:28
[deleted comment]
I have a class
public class A
{
public A(int , string , string){
//Do something
}
}
public class B
{
public void someMethod()
{
A a = new A(int, String, String)
//Do something
}
}
Tests Case
@PrepareForTest(A.class)
public class BTests
{
A aObj = Mockito.mock(A.class);
PowerMockito.whenNew(A.class).withAnyArguments().thenReturn(aObj);
B b= new B();
b.someMethod() // When i do this it is actually calling the constructor of A.
}
When calles someMethod , it actually called the constructor of A.
Can you let me khow where i am making miskate. I am using testNg.
Thnaks
Original comment by g.ranjan...@gmail.com
on 21 May 2013 at 10:05
To update #14, has this been resolved yet?
Original comment by nka...@gmail.com
on 1 Apr 2015 at 6:33
Original issue reported on code.google.com by
mohamed....@gmail.com
on 24 Oct 2012 at 11:42