JUnit Easymock Unexpected method call - junit

I'm trying to setup a test in JUnit w/ EasyMock and I'm running into a small issue that I can't seem to wrap my head around. I was hoping someone here could help.
Here is a simplified version of the method I'm trying to test:
public void myMethod() {
//(...)
Obj myObj = this.service.getObj(param);
if (myObj.getExtId() != null) {
OtherObj otherObj = new OtherObj();
otherObj.setId(myObj.getExtId());
this.dao.insert(otherObj);
}
//(...)
}
Ok so using EasyMock I've mocked the service.getObj(myObj) call and that works fine.
My problem comes when JUnit hits the dao.insert(otherObj) call. EasyMock throws a *Unexpected Method Call* on it.
I wouldn't mind mocking that dao in my test and using expectLastCall().once(); on it, but that assumes that I have a handle on the "otherObj" that's passed as a parameter at insert time...
Which of course I don't since it's conditionally created within the context of the method being tested.
Anyone has ever had to deal with that and somehow solved it?
Thanks.

You could also use EasyMock.isA(OtherObj.class) for a little more type safety.

If you can't get a reference to the object itself in your test code, you could use EasyMock.anyObject() as the expected argument to yourinsert method. As the name suggests, it will expect the method to be called with.. well, any object :)
It's maybe a little less rigorous than matching the exact argument, but if you're happy with it, give it a spin. Remember to include the cast to OtherObjwhen declaring the expected method call.

The anyObject() matcher works great if you just want to get past this call, but if you actually want to validate the constructed object is what you thought it was going to be, you can use a Capture. It would look something like:
Capture<OtherObj> capturedOtherObj = new Capture<OtherObj>();
mockDao.insert(capture(capturedOtherObj));
replay(mockDao);
objUnderTest.myMethod();
assertThat("captured what you expected", capturedOtherObj.getValue().getId(),
equalTo(expectedId));
Also, PowerMock has the ability to expect an object to be constructed, so you could look into that if you wanted.

Note also that if you use EasyMock.createStrictMock();, the order of the method calls is also important and if you break this rule, it would throw an unexpected method call.

Related

Calling mock method instead of real method with Mockito

I have a method which needs to be called instead of the real method.
Instead I get an exception. Can somebody please help me with right way to call the alternate method through mockito ?
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 4 recorded.
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
//Code starts here
class A{
public realMethod(String s, Foo f){
}
}
class B {
public mockMethod(String s, Foo f) {
}
}
class UnitTestClass{
ClassA mock = new ClassA();
mock.when(realMethod(any(String.class), any(Foo.class))).thenReturn(mockMethod(any(String.class),any(Foo.class));
}
You are getting mocking wrong.
Here:
thenReturn(mockMethod(any(String.class),any(Foo.class));
That simply doesn't make sense.
Mocking works like this:
you create a mock object of some class, like A mock = mock(A.class)
you specify interactions on that mock object
Your code implies that you think that these specifications are working like "normal" code - but they do not!
What you want to do: when some object is called with certain parameters, then return the result of another method call.
Like in:
when(a.foo(x, y)).thenReturn(b.bar(x, y))
That is what want you intend to do. But thing is: it isn't that easy. You can't use the any() matcher in thee thenReturn part in order to "provide" the arguments that were passed in the when() call before! It is that simply.
Mocking should be within a specific unit test to get a specific result.
Meaning: you are not writing an ordinary program where it would make any sense to "forward" parameters to another call. In other words; your code should more look like:
when(mock.realMethod("a", someSpecificFoo)).thenReturn(mockMethod("a", someSpecificFoo))
That is the only thing possible here.
Beyond that, you might want to look into a Mockito enter link description here instead.
Long story short: it simply looks like you don't understand how to use mocking frameworks. I suggest that you step back and read/work various tutorials. This is not something you learn by trial and error.

powermockito static and non static method chain

I want non-static method of an object returned by a static factory method to return a specific result.
After I have done this setup my test code will be calling the ConnectionFactory.getConn("ABC") indirectly through another piece of code which is being tested.
PowerMockito.when(ConnectionFactory.getConn("ABC").getCurrentStatus()).thenReturn(ConnectionStatus.CONNECTED);
I get a NPE for the above statement.
I already have #PrepareForTest({FXAllConnectionFactory.class, ConnectionStatus.class}) at the beginning of my junit test class.
What would be the correct way of doing it?
Thanks in advance :)
I guess there is no point in creating a fluent/chained call for your test setup.
You see:
PowerMockito.when(ConnectionFactory.getConn("ABC").getCurrentStatus()).thenReturn(ConnectionStatus.CONNECTED);
is probably meant to configure two calls:
ConnectionFactory.getConn("ABC") and then
getCurrentStatus() on the result of that first call
And what makes you think that PowerMockito magically knows what should be returned by that first call to getConn()?
In other words:
First provide a mocked Connection object X; and configure your mocks so that getConn() returns that object
In addition to that, you have to configure X to return the desired value upon a call to getCurrentStatus() ... on X!
So, the answer is actually: what you want to do isn't possible. The idea is; you specify behavior such as:
when A.foo() is called; then return some X
There is no magic power within PowerMockito to turn
when A.foo().bar() is called thren return Y
into
when A.foo() is called, return X; when X.bar() is called return Y
You have to specify that step by step.

Mockito - You cannot use argument matchers outside of verification or stubbing - have tried many things but still no solution

I have the following piece of code:
PowerMockito.mockStatic(DateUtils.class);
//And this is the line which does the exception - notice it's a static function
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
The class begins with:
#RunWith(PowerMockRunner.class)
#PrepareForTest({CM9DateUtils.class,DateUtils.class})
And I get org.Mockito.exceptions.InvalidUseOfMatchersException...... You cannot use argument matchers outside of verification or stubbing..... (The error appears twice in the Failure Trace - but both point to the same line)
In other places in my code the usage of when is done and it's working properly. Also, when debugging my code I found that any(Date.class) returns null.
I have tried the following solutions which I saw other people found useful, but for me it doesn't work:
Adding
#After
public void checkMockito() {
Mockito.validateMockitoUsage();
}
or
#RunWith(MockitoJUnitRunner.class)
or
#RunWith(PowerMockRunner.class)
Change to
PowerMockito.when(new Boolean(DateUtils.isEqualByDateTime(any(Date.class), any(Date.class)))).thenReturn(false);
Using anyObject() (it doesn't compile)
Using
notNull(Date.class) or (Date)notNull()
Replace
when(........).thenReturn(false);
with
Boolean falseBool=new Boolean(false);
and
when(.......).thenReturn(falseBool);
As detailed on the PowerMockito Getting Started Page, you'll need to use both the PowerMock runner as well as the #PrepareForTest annotation.
#RunWith(PowerMockRunner.class)
#PrepareForTest(DateUtils.class)
Ensure that you're using the #RunWith annotation that comes with JUnit 4, org.junit.runner.RunWith. Because it's always accepted a value attribute, it's pretty odd to me that you're receiving that error if you're using the correct RunWith type.
any(Date.class) is correct to return null: Rather than using a magic "matches any Date" instance, Mockito uses a hidden stack of matchers to track which matcher expressions correspond to matched arguments, and returns null for Objects (and 0 for integers, and false for booleans, and so forth).
So in the end,what worked for me was to export the line that does the exception to some other static function. I called it compareDates.
My implementation:
In the class that is tested (e.g - MyClass)
static boolean compareDates(Date date1, Date date2) {
return DateUtils.isEqualByDateTime (date1, date2);
}
and in the test class:
PowerMockito.mockStatic(MyClass.class);
PowerMockito.when(MyClass.compareDates(any(Date.class), any(Date.class))).thenReturn(false);
Unfortunately I can't say I fully understand why this solution works and the previous didn't.
maybe it has to do with the fact that DateUtils class is not my code, and I can't access it's source, only the generated .class file, but i'm really not sure about it.
EDIT
The above solution was just a workaround that did not solve the need to cover the DateUtils isEqualByDateTime call in the code.
What actually solved the real problem was to import the DateUtils class which has the actual implementation and not the one that just extends it, which was what I imported before.
After doing this I could use the original line
PowerMockito.mockStatic(DateUtils.class);
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
without any exception.
I had a similar problem with TextUtils in my Kotlin Test Class
PowerMockito.`when`(TextUtils.isEmpty(Mockito.anyString())).thenReturn(true)
Resolved it by adding below code on top of my Test Class
#PrepareForTest(TextUtils::class)
and called mockStatic this before PowerMockito.`when`
PowerMockito.mockStatic(TextUtils::class.java)

mockito when thenReturn does not return stubbed array list

List<Populate> fullAttrPopulateList = getFullAtrributesPopulateList(); //Prepare return list
when(mockEmployeeDao.getPopulateList(null)).thenReturn(fullAttrPopulateList);
MyDTO myDto = testablePopService.getMyPopData(); //Will call mockEmployeeDao.getPopulateList(null)
//verify(mockEmployeeDao,times(1)).getPopulateList(null);
assertEquals(fullAttrPopulateList.size(), myDto.getPopData().size()); //This fails because myDto.getPopData().size() returns 0
As you can see testablePopService.getMyPopData() calls mockEmployeeDao.getPopulateList(null) but when I debug it a zero sized list returns instead of the stubbed array list which is prepared by getFullAtrributesPopulateList();
If I uncomment the verify statement, it passes the test meaning getPopulateList(null) behavior does get called.
Can anyone give me some advice why my stubbed array list cannot be returned even it is verified the expected behavior happened? How come an empty array list returns rather than a null if I did something wrong?
First, check that the method is non-final and visible throughout its hierarchy. Mockito can have trouble mocking methods that are hidden (e.g. overriding a package-private abstract class's implementation); also, Mockito is entirely unable to mock final methods, or even to detect that the method is final and warn you about it.
You may also want to check that your call is using the overload you expect. Mockito's default list return value is an empty list, so you may simply stubbing one method and seeing the default value for another. You can see which method interactions Mockito has added by adding a call to verifyZeroInteractions temporarily, and Mockito will throw an exception with a list of calls that mock has received. You could also add verifyNoMoreInteractions, and even leave it in there, at the expense of test brittleness (i.e. the test breaks when the actual code continues to work).

actionscript 3 How to access 'this' in inline function

I am trying to do something like:
String.prototype.print=function(){trace(??????)}
I can't for the life of me figure out a way to get at the string! Yes I know there are other ways to approach this etc. but...
Not sure what the problem is, using this works fine in anonymous functions.
String.prototype.print=function():String{return "printed "+this;}
var o:Object = "foo";
trace(o.print()); // traces: printed foo
I just tricked the compiler to use an object, because "foo".print() causes
Error: Call to a possibly undefined method print through a reference with static type String.
It looks like you are mixing ActionScript 2 into your ActionScript 3 code. As kapep said, using "this" will work in your example. That is, this is perfectly valid code:
String.prototype.print=function(){trace(this)}
Of course, you are missing a semi-colon but that shouldn't matter:
String.prototype.print=function(){trace(this);} //semi-colon after 'trace(this)'
Depending on your development environment, you might be having trouble viewing trace statements, in general. In Flex Builder, for example, trace statements don't show up at all unless you are in Debug mode. Insert another call to trace to verify that you can see trace statements.
As you said, there are many other ways to approach this, such as extending the String class and adding your "Print" function. If you really can't get this to work, then trying an ActionScript 3 (i.e. Object-Oriented) approach might be your best option.