Mock Abstract Class in EasyMock - java

I am using EasyMock 2.4 and can't upgrade to latest version due to dependencies.
I need to mock abstract class but not able to do it with createMock method.
It throws an error that class is not an interface.
Can anyone help me in solving this problem?
There is an abstract class called ClassA (I can't modify this class):
public abstract class ClassA {
}
There is another MyTest class which mocks ClassA:
public class MyTest {
private ClassA mockClassA;
#Before
public void setup() {
mockClassA = createMock(ClassA.class); //Line number: 28
}
}
while running this it throws below exception at createMock call:
java.lang.IllegalArgumentException: ClassA is not an interface
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:590)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
at java.lang.reflect.WeakCache.get(WeakCache.java:127)
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
at org.easymock.internal.JavaProxyFactory.createProxy(JavaProxyFactory.java:13)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:40)
at org.easymock.EasyMock.createMock(EasyMock.java:60)
at mypackage.MyTest.setup(MyTest.java:28)

EasyMock prior to v3.0 was using Java proxies mechanism to create mocks. This mechanism is capable only of creating proxies for interfaces, so there is no way you can mock a class (abstract class) with easy mock without upgrading to v3.0 at least.
You have the following options:
Upgrade EasyMock to v3.0+ (what prevents your from?)
Use other mocking library in parallel with EasyMock (e.g. Mockito)
Create your own subclass of ClassA in test and override methods there for testing. But this one is clearly a workaround that may not provide you with enough flexibility.
Actually what do you expect from your mock? (E.g. to stub some method calls, or to do some method call verifications, other...)

EasyMock Class extension worked to create mock object for class or interface. I used import static org.easymock.classextension.EasyMock.*; instead of import static org.easymock.EasyMock.*;

Yes. Prior to EasyMock 3, you need the class extension to mock classes. However, latest EasyMock versions have not much dependencies (only Objenesis in fact).
Which one is blocking you?

Related

Change the behavior of a method to use in unit Test in Java

my problem is that my unit test are slow because I'm publishing in a topic in those unit test, I would like to mock or change its behavior in some way. I was thinking in use reflection for this class and change the method behavior but I'm not sure if that is possible.
This is the behavior that I like to mock or change:
TopicCall.builder()
.toTopic(XXXX)
.withAttribute(XXXXXX, XXXXX)
.withAttribute(XXXXX, XXXXXX)
.withAttribute(XXXXX,XXXXX)
.publish();
I would like to do this because publis() is a real invocation and the test is slow and causing some problems in jenkins, because several unit test are publishing at the same time.
The Topic class is a public class with a static builder method which return a class instance, just like the next one:
public static TopicCall builder() {
return new TopicCall();
}
My problem is that I just acceding the method of this class from outside and I'm not sending the class in the constructor as example and I'm not able to mock its behavior, I'm not able to modify the TopicCall class because it is a .class utility from a jar, besides that I'm not able to use PowerMockito or another library, just Mockito, is there any way to achieve that?
Thanks!
Disclaimer: I missed the fact that PowerMock is forbidden for the author, but the answer could be useful for other users with the same problem.
PowerMock
As far as you want to mock a static method, then Mockito is not the solution.
This could be done using PowerMock.
PowerMock uses ClassLoader way for mocking, which could significantly increase tests time to run.
Here is an examle on Baeldung how to mock static methods.
Solution scratch:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ TopicCall.class })
public class Test {
#Test
void test() {
mockStatic(TopicCall.class);
when(TopicCall.builder()).thenReturn(/*value to be returned*/ null);
// the test code...
}
}

How to handle Static method call of ThirdParty class while junit testing using Mockito?

I am facing problem while testing method using Mockito.
please check testMethodToBeTested() method of JunitTestCaseClass, which has to handle static method call of thirdparty class.
class ClasssToBeTested{
public String methodToBeTested() {
String result = ThirdPartyUtilClass.methodToBeCall();
return result;
}
}
class ThirdPartyUtilClass{
public static String methodToBeCall(){
return "OK";
}
}
// JunitTestCase which will test method "methodToBeTested()" of ClasssToBeTested class
class JunitTestCaseClass{
#InjectMocks
private ClasssToBeTested classsToBeTested;
#Test
public void testMethodToBeTested() {
//How to handle ThirdPartyUtilClass.methodToBeCall(); statement in unit testing
String result = classsToBeTested.methodToBeTested();
Assert.assertNotNull(result);
}
}
Please help & Thanks in Advance.
I think this is your answer why it is not working:
https://github.com/mockito/mockito/wiki/FAQ
What are the limitations of Mockito
Mockito 2.x specific limitations
Requires Java 6+
Cannot mock static methods
Cannot mock constructors
Cannot mock equals(), hashCode().
Firstly, you should not mock those methods. Secondly, Mockito defines and depends upon a specific implementation of these methods. Redefining them might break Mockito.
Mocking is only possible on VMs that are supported by Objenesis. Don't worry, most VMs should work just fine.
Spying on real methods where real implementation references outer Class via OuterClass.this is impossible. Don't worry, this is extremely rare case.
If you really want to mock static methods then PowerMock is your solution.
https://github.com/powermock/powermock/wiki/mockito

When you mock a class in mockito framework, do you stand up actual mock class manually?

I am fairly new to mockito framework. I've been reading upon multiple tutorials in regards to it. One of them I was following is this: https://www.tutorialspoint.com/mockito/mockito_first_application.htm
There is a statement creating a mock of Stock Service.
In this example, we've created a mock of Stock Service to get the dummy price of some stocks
My question is Stock Service is a real service class or mock service class you have to manually stand up for mimicking the real service class. I am a bit confused. Having basic understanding of junit framework. What I had practiced before was if there is a service class Foo then I used actual class that provides all the exposed methods.
public class Foo {
public Foo() { } // construtor
public String returnAddress(String userId) {
// ...
return dataAccesobj.getAddress(userId);
}
}
Calling foo.returnAddress(..) in unit test if I remember right.
The reason I am asking this question is while I was working with mockitoto create a test method for a class, I ran into a unique(?) challenge.
I started with a real service class which depends on its super class constructor to return its instance. The challenge I ran into was this super class constructor initiates DB connection and loading/parsing properties files which I do not need for my test. I was thinking about how to prevent DB connection and loading/reading prop files....
I thought I read from one of mockito tutorials you can isolate testing without having such services. I tried with #Mock and #Spy (not fully understanding well still what they are for..) but it didn't make a difference for output (maybe I misused those annotations).
So what I did was actually creating fake/mock class out of real service class (e.g. Foo) by simply copying it and renamed it as FooMock and put it in src/test/java folder in where unit test class is running from. I kept the mock class exactly same as the real service class except taking out unwanted logic such as db connection or loading/reading prop file for env specific. By doing that I was able to test one of exposed methods that read ldap directory...
I am sorry I got digressed but hope my point is clear at this point. I am not sure the way I handled this situation is right or wrong. I'd appreciate experienced engineers would clarify the way I handled the matter is acceptable in mockito way or not. If not, then plz advise me best way to handle it.
With Mockito,
a mock is an implementation of a wrapper class.
The mock object "wraps" the target of the mock
(the service in your example)
and allows you to define functionality of each method.
There are two mocked functionality options with Mockito;
call the wrapped method and don't call the wrapped method.
I don't know when it would make sense to call the wrapped method,
so I always use don't call the wrapped method.
After you create the mock,
use the Mockito.doReturn(returnvalue).when(mockObject).method(method parameters) method to mock functionality.
Edit: some more info.
I will assume that you are using junit v4.
The details of this will differ based on the the junit major release number,
but the actual work will be the same.
Use annotations to define your Mock objects (#Mock),
except in a few special cases.
This will create mocks of non-final classes,
abstract classes,
and interfaces.
Create a "before-test" method using the #Before annotation;
I traditionally name this method preTestSetup,
but the actual name does not matter.
Call MockitoAnnotations.initMocks(this) as the first line of code
in the "before-test" method.
This will find the #Mock annotations and instantiate a mock for each.
Use the ReflectionTestUtils.setField method to inject the mocks into your object (assuming that you don't have setter methods,
which I traditionally don't like).
Define the mocked functionality of each method using the Mockito.doReturn(returnvalue).when(mockObject).method(method parameters) technique.
Here is some example code
(caveat:
this should be fully functional,
but I did not compile it):
public interface MyService
{
String blammy(SomeParameter parameter);
}
public class UsesMyService
{
#Autowired
private MyService myService;
public String kapow(final SomeParameter parameter)
{
return myService.blammy(parameter);
}
}
public class UnitTestUsesMyService
{
private UsesMyService classToTest;
#Mock
private MyService mockMyService;
#Mock
private SomeParameter mockSomeParameter;
#Before
public void preTestSetup()
{
MockitoAnnotations.initMocks(this);
classToTest = new UsesMyService();
doReturn("Blam").when(mockMyService).blammy(mockSomeParameter);
ReflectionTestUtils.setField(
classToTest,
"myService",
mockMyService);
}
#Test
public void kapow_allGood_success()
{
final String actualResult;
actualResult = classToTest.kapow(mockSomeParameter);
assertNotNull(actualResult); // Not strictly necessary.
assertEquals(
"Blam",
actualResult);
}
}

PowerMockito: Trying to mock System class methods or any other Final class method

I am trying to mock System class to get a constant value for currentTimeMillis().
Since I cannot use Mockito for mocking final classes I am using PowerMock, but when mocking the System.currentTimeMillis() I am geting error "Cannot resolve method when(long)".
My code looks like:
PowerMockito.mockStatic(System.class);
when(System.currentTimeMillis()).thenReturn(CURRENT_TIME_STAMP);
I have also annoted my class as:
#RunWith(PowerMockRunner.class)
#PrepareForTest(System.class)
public class DateTimeUtilsTest {
Resolved.
It should be like
PowerMockito.when(System.currentTimeMillis()).thenReturn(CURRENT_TIME_STAMP);
or import the PowerMockito statically like
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
Similarly, one can mock any of the System class methods or can mock any other final class.
This is why you should write tests first, then you don't write untestable code.
Your code should not access transient statics directly, but through a component you can mock.

Mocking Enum class in TestNG (Incomprehension of solution)

I need to mock enum class. (Using Mockito and PowerMockito in TestNG)
I was searching for solution, and as a result I found many similar answers:
http://ambracode.com/index/show/285802
How to mock an enum singleton class using Mockito/Powermock?
mocking a singleton class
How to mock a method in an ENUM class?
In each provided solution I need to add #PrepareForTest adnotation and mock using powermock.
#PrepareForTest( MyEnum.class)
#Test
public void myTest() {
MyEnumClass mockInstance = PowerMockito.mock(MyEnumClass .class);
Whitebox.setInternalState(MyEnumClass.class, "INSTANCE", mockInstance);
PowerMockito.mockStatic(MyEnumClass.class);
//DoReturn/when and so on...
}
But I still do not understand how it suposed to work? If I try it, I will get
java.lang.IllegalArgumentException: Cannot subclass final class class
How I can make "MyEnumClass mockInstance = PowerMockito.mock(MyEnumClass .class);" if it is enum and final?
I had that problem before i started searching for the result, but every answer looks the same.
What am I missing?

Categories