Mockito: Unable to mock a static & non-static method - java

I am unable to mock anything(static or non static methods) from mockito,
These are my classes,
Calculations.java
public class Calculations {
public void printZero() {
System.out.println("zero");
}
public static void printOne() {
System.out.println("one");
}
}
This is my PostData.java
public class PostData {
public static Calculations calc = new Calculations();
public static void postTheData() {
calc.printZero();
Calculations.printOne();
}
}
The unit test class,
TestClass.java
public class TestClass {
#Test
public void addTest() {
Calculations lmock = mock(Calculations.class);
// can't have Calculations.calc.printZero() in when() :cause: argument passes to when() must be a mock object.
doNothing().when(lmock).printZero();
// cause: method when(void) is undefined for the type TestClass
// when(lmock.printZero()).doNothing();
// cause: argument passed to when() must be a mock object.
// doNothing().when(Calculations.printOne());
PostData.postTheData();
}
}
Its compiled and its printing "zero" as well as "one" in my output, which ideally should have been ignored.
I am using cloud-mockito-all-1.10.19.jar for mockito.
And junit's latest jar file.
I know I am missing something here, but can't figure out what! It would be a great help if you can answer me.

The problem is that PostData doesn't use the mocked Calculations object.
In order to do it, you can add a setter for calc field (and perhaps change it to be non static) and set PostData's calc field to the mocked one.

Related

Mocking static method in Java

Is there way to mock for unit test static method in Java without executing the method actual implementation? Actual implementation launches the process that cannot be done in unit test context.
public class MyExecutor {
public static int execute(...) {
Process pr = Runtime.getRuntime().exec(...)
int status = pr.waitFor();
return status;
}
public MyClass {
public void methodToUnitTest(...){
MyExecutor.execute(...)
}
I want to mock MyExecutor.execute and verify both its invocation and its params when unit testing MyClass.methodToUnitTest but without actual execution of this method.
I read that PowerMockito can mock static method but it does not prevent actual implementation from being executed.
Wrap the static class MyExecutor in a non-static class. Extract the methods of your new non-static class into an interface. Replace the dependencies to static class with the interface - use dependency injection to provide MyExecutor instances to MyClass:
public MyExecutorAdapter implements Executor{
public void execute() {
MyExecutor.execute() //call to static code
}
}
public MyClass {
private Executor myExecutor;
public MyClass(Executor myExecutor){ //MyExecutorAdapter instance can be injected here
this.myExecutor = myExecutor;
}
public void methodToUnitTest(...){
myExecutor.execute(...)
}
}
Now, with the interface, you can easily mock or provide a fake implementation for testing purposes. In your case, you probably need to have a mock to check if the execute method was called.
This is basically known as Adapter pattern

Powermock verifyPrivate does not work with any()

I have a private method whose invocation I want to test without caring about the arguments. I want to test if it was called at all or not.
MyClass.java
public void doStuff(){
unload(args);
}
private void unload(List<String> args) {
//
}
So I used following:
MyClasstest.java
MyClass myClass = PowerMockito.spy(new MyClass());
myClass.doStuff();
verifyPrivate(myClass, times(1)).invoke("unload",any(List.class));
// verifyPrivate(myClass, times(1)).invoke("unload",any()); //same result with this
This test fails with following exception:
Wanted but not invoked com.MyClass.unload(
null );
However, there were other interactions with this mock .......
(actual values with which it was called)
Can verifyPrivate be called with only actual arguments & not with any()?
Here is a working example of what you are trying to do:
You might just missing the #PrepareForTest annotation, which has to point to the correct class. If your class is an external one use #PrepareForTest(MyClass.class), the example below shows it with an internal class.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClassTest.class)
public class MyClassTest {
static class MyClass {
public void doStuff(){
unload(null);
}
private void unload(List<String> args) {
}
}
#Test
public void test() throws Exception {
MyClass myClass = PowerMockito.spy(new MyClass());
myClass.doStuff();
PowerMockito.verifyPrivate(myClass, Mockito.times(1)).invoke("unload", Mockito.any());
}
}
Note that you should consider whether you really want to do this in a UnitTest. Normally your UnitTest should not be concerned about whether a private method is used or not, it should be focused on verifying that the correct result is returned or the correct object state is reached.
By adding knowledge about the internal behaviour of the class into it, you test is tightly coupled to the implementation which might not be a good thing.

PowerMockito private void method issue

I have below class
class PowerMockitoTest{
private void TestPrivateMethod(){
System.out.println("Inside private method");
}
public void TestPublicMethod(){
System.out.println("Inside public method");
TestPrivateMethod();
}
}
I have created Test class as below
#RunWith(PowerMockRunner.class)
public class PowerMockitoExampleTest {
#Test
public void test() throws Exception {
PowerMockitoTest testclass = PowerMockito.spy(new PowerMockitoTest());
PowerMockito.doNothing().when(testclass,"TestPrivateMethod");
testclass.TestPublicMethod();
}
}
Instead of getting OP as 'Inside public method' I am getting very strange OP as 'Inside private method'. Though i have stubbed private method to do nothing its getting called as well as sysout for public method is not getting printed.
Its working fine when i used PowerMockito.doAnswer() but it requires method to be at package level instead of private.
Write it this way:
PowerMockitoTest testclass = PowerMockito.spy(new PowerMockitoTest());
try {
PowerMockito.doNothing().when(testclass, PowerMockito.method(PowerMockitoTest.class, "TestPrivateMethod")).withNoArguments();
} catch (Exception e) {
e.printStackTrace();
}
testclass.TestPublicMethod();
btw:
Testing is about mocking input and investigating outputs (it can be state of module, result of function or calls to another functions).
You should not mock private methods, as their result should not be treated as an input becouse they are not visible from outside.
The missing part in your code i believe is the #PrepareForTest part. You have to add class name with #PrepareForTest after #RunWith annotation
#RunWith(PowerMockRunner.class)
#PrepareForTest({Class1.class, Class2.class})
public class ClassTest

Testing for void methods dependency using EasyMock

I have a Mainclass that I need to test which is dependent on other class.
Now I am creating a mock for that class
How to test void methods using easymock
MainClass{
mainClassMethod(){
dependencyClass.returnVoidMethod();
//other code
}
}
TestClass{
#Before
setUpMethod(){
DependencyClass dependencyClassMock = EasyMock.createMock(DependencyClass.class);
}
#Test
testMainClassMethod(){
EasyMock.expect(dependencyClassMock.returnVoidMethod()).andRetur //this is not working
dependencyClassMock.returnVoidMethod();
EasyMock.expectLastCall().anyTimes(); //If I use this, it is invoking the method.
}
}
//My dependency class code
DependencyClass implements ApplicationContextAware{
private static ApplicationContext applicationContext;
private static final String AUTHENTICATION_MANAGER = "authenticationManagers";
returnVoidMethod(){
ProviderManager pm = (ProviderManager) getApplicationContext().getBean(AUTHENTICATION_MANAGER); //this is returning null
}
//othercode
//getters and setters of application context
}
As described in the Easymock Documentation you don't put the method inside an expect() (since there is no return). You can just call the mocked method by itself and if it is in "record" mode then it is implied an expect.
dependencyClassMock.returnVoidMethod();
If you need to throw an Exception or say the method can be called anyTimes() you can use expectLastCall()
#Test
public void testMainClassMethod(){
dependencyClassMock.returnVoidMethod();
EasyMock.expectLastCall().anyTimes();
...
//later to replay the mock
EasyMock.replay(dependencyClassMock);
//now this method is actually called
dependencyClassMock.returnVoidMethod();
}
EDIT : Just noticed that you don't have the dependencyClassMock as field:
public class TestClass{
DependencyClass dependencyClassMock
#Before
setUpMethod(){
dependencyClassMock = EasyMock.createMock(DependencyClass.class);
}
...//rest of class is as described above
#dkatzel
the test is completely wrong..... you are calling manually a method and the you verify if it was called...of course it was! ...that's not the right way (my opinion)
A better way (my opinion) would be to extend the mehod class you would like to test, override that method and in the body just put a boolean variable as a flag to k now if the method was called or not....you don't even need to use EasyMock
Example
Class DependencyClass {
public void returnVoidMethod() {
[.... content ...]
}
}
Class A_test {
#Test
public void checkVoidMethodCalled() {
A_mod obj = new A_mod();
mainClassMethod();
assertTrue(obj.called);
}
Class A_mod extends DependencyClass {
boolean called = false;
#Override
public void returnVoidMethod() {
called = true;
}
}
}
You are welcome.

Dependency verify functions call mockito

I want create unit test to test a class which contains another object. I have created a mock to this second object.
When I test a method of my first class, I want verify if the functions of the second object are called. For this, I use the function verify(mock).myfunction();
My problem is that the same function of my object 2 can be called by several function of my first class.
When I write the test class, I write a test function by function but it seems that the "times" isn't reset at the beginning of a test method.
I don't know if I am clear, therefore, an example :
public class Main {
public Object o = createObject();
public void function1(){
o.function();
}
public void function2(){
o.function();
}
public Object createObject() {
return new Object() ;
}
public class MainTest {
private static Main main;
#BeforeClass
public static void setUp() throws Exception {
final Object mockO = mock(Object.class);
main = new Main() {
#Override
public Object createObject() {
return mockO;
}
};
}
#Test
public void testfunction1(){
verify(main.world[0], never()).function();
main.function1();
verify(main.world[0]).function();
}
#Test
public void testfunction2(){
verify(main.world[0], never()).function();
main.function2();
verify(main.world[0]).function();
}
If I test testfunction1() and testfunction2() ignored, it's work.
If I test testfunction2() and testfunction1() ignored, it's work.
But if the two tests are executed, I have an error :
org.mockito.exceptions.verification.NeverWantedButInvoked:
Object.function();
Never wanted here :
-> at test.MainTest.testfunction1
but invoked here :
at source.Main.function2
How I can test independently the two functions?
Rename your setUp() method into something else, make it a non-static method, and make it #Before and not #BeforeClass:
private Main main;
#Before
public void initMain()
{
// what you already do
}
#BeforeClass methods run once before all tests in a class, while #Before methods are run once before each test.

Categories