What happens when you use mockStatic() on a non-static class? - java

I'm reading some test code that calls mockStatic(MyClass.class), but MyClass is neither static nor does it contain static methods.
Are there other benefits of using mockStatic()?
Not sure if related, but PowerMock is also used in the test code.

I cannot comment so I just reply here..
According to its latest documentation, Mockito doesnt have mockStatic(), so I think this comes from PowerMock. You can go in to the method declaration to see at least the method comes from which module.
For Powermock, the class inside mockStatic() doesnt have to be static class. The goal of mockStatic is to mock the static method. See here: https://code.google.com/p/powermock/wiki/MockStatic

Related

Getting NotAMockException on Calendar.getInstance() mocking

I am trying to mock Calendar.getInstance() for unit testing purpose.
I am thus using PowerMock (powermock-core:2.0.4 & powermock-module-junit4:2.0.4) and its Mockito API (powermock-api-mockito2:2.0.4).
I am well aware that similar cases do exist, but I am facing an exception that does not seem to appear on other's case.
Indeed, when doing
mockStatic(Calendar.class);
when(Calendar.getInstance()).thenReturn(aCalendar);
on a test method within a class annotated with
#RunWith(PowerMockRunner.class)
#PrepareForTest({DateUtils.class})
I get the following error : org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class.
What did I do wrong and how to solve it ?
Thanks
There are a couple issues here.
mockStatic(Calendar.class); this should be in setUp method or something.
Then you do this.
verifyStatic(Calendar.class)
when(Calendar.getInstance()).thenReturn(aCalendar);
Another important thing is the following,
#RunWith(PowerMockRunner.class)
#PrepareForTest({DateUtils.class, Calendar.class})
Any class that has static method you would like to mock should be included in #PrepareForTest either at the class level or method level, if it is used only once.

How to mock new instance where it return interface reference

I have a scenario like this
MyInterface myObject = new MyInterfaceImplementedClass();
myObject.get(...)
I want to mock the MyInterfaceImplementedClass, I tried like below
private MyInterface mockMyObject
private MyInterfaceImplementedClass mockMyClassObject
// the below compilation error
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyObject);
// no compilation error but not giving mocking instance at runtime
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyClassObject);
Please help me on this
Solved in the comments:
after adding my test class in side #PrepareForTest, it works as expected
In short, Mockito writes a generated subclass for the class you're trying to mock, which allows it to intercept the behavior of overridable methods (i.e. non-final instance methods). This handles all interfaces and most abstract and concrete classes. However, if you're trying to mock the behavior of final or static methods, including constructors, there's nothing Mockito can do1: the consuming class contains a reference to the exact real implementation without a lookup to the virtual method table. The only way out is to rewrite and replace the bytecode of an existing class, which is exactly what PowerMock does.
It can often just overwrite the class you're trying to mock, but in certain circumstances you need to list the class under test or the test class itself.
Consequently, almost all tests that exercise PowerMock's features require a #PrepareForTest, as well as a #RunWith statement that ensures that the test class uses PowerMock's classloader to enable that rewriting.
1 since Mockito 2.1, Mockito can use instrumented classloaders to do some of the things that were previously only available in PowerMock.

How to mock main

My class Under Test access Main itself (Main.doSomething)
I would like to mock Main class to avoid setting up the whole process with all the hasltle
how can I do so?
I am using Powermock with Mockito.
Main is not a reserved word for a class in Java. It means you can test like any other class. It depends if doSomething is static and/or final or not.
Provided that having to mock static methods is a bad practice (your method shouldn't be static if it is supposed to be mocked: if the class is difficult to test – refactor the class -- http://monkeyisland.pl/2008/01/14/mockito/).
Nevertheless, here is how you do it with powermock:
PowerMockito.mockStatic(Main.class);
PowerMockito.when(Main.doSomething()).thenReturn(something);
Here the documentation: http://code.google.com/p/powermock/wiki/MockStatic
For mocking static members do:
Whitebox.setInternalState(Main.class, doSomething);
A more powerful Mocking Framework is JMockit. It gives enhanced mocking and stubbing functionality.
CheckOut: http://code.google.com/p/jmockit/

How do I mock Object.getClass?

I'm working on a Java project want to write a unit test for an .equals method I have in a DTO. In the .equals method, there is a .getClass() method called by both objects under test. I want to mock this, but I can't tell what type of object it wants. I tried,
when(mockRoomInv.getClass()).thenReturn(RoomInv.class);
but sure as heck didn't do anything. What is the return type of getClass, and how do I manipulate it?
As Object.getClass() is final, you cannot mock that method with Mockito. I would strongly advice you to refactor your code to inject the class in another way. If that's not possible, you could try out powermock, where you could mock any final method. Object.getClass() is a bit special, so be sure to set MockGateway.MOCK_GET_CLASS_METHOD = true in powermock.
Object.getClass() is a final method, so you cannot mock it with Mockito.
You can mock static and final methods (as this one) and even private methods with Powermock (it's a quite cool tool ;) available at https://github.com/powermock/powermock.
You can use it with Mockito as explained in the Mockito wiki article. There you will find some useful examples.

annotation to make a private method public only for test classes [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
Who has a solution for that common need.
I have a class in my application.
some methods are public, as they are part of the api,
and some are private, as they for internal use of making the internal flow more readable
now, say I want to write a unit test, or more like an integration test, which will be located in a different package, which will be allowed to call this method, BUT, I want that normal calling to this method will not be allowed if you try to call it from classes of the application itself
so, I was thinking about something like that
public class MyClass {
public void somePublicMethod() {
....
}
#PublicForTests
private void somePrivateMethod() {
....
}
}
The annotation above will mark the private method as "public for tests"
which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.
any thoughts?
is there an annotation like this?
is there a better way to do this?
it seems that the more unit tests you write, to more your inforced to break your encapsulation...
The common way is to make the private method protected or package-private and to put the unit test for this method in the same package as the class under test.
Guava has a #VisibleForTesting annotation, but it's only for documentation purposes.
If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.
The JUnit Doc says:
Testing private methods may be an indication that those methods should be moved into another class to promote reusability.
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.
Consider using interfaces to expose the API methods, using factories or DI to publish the objects so the consumers know them only by the interface. The interface describes the published API. That way you can make whatever you want public on the implementation objects and the consumers of them see only those methods exposed through the interface.
dp4j has what you need. Essentially all you have to do is add dp4j to your classpath and whenever a method annotated with #Test (JUnit's annotation) calls a method that's private it will work (dp4j will inject the required reflection at compile-time). You may also use dp4j's #TestPrivates annotation to be more explicit.
If you insist on also annotating your private methods you may use Google's #VisibleForTesting annotation.
An article on Testing Private Methods lays out some approaches to testing private code. using reflection puts extra burden on the programmer to remember if refactoring is done, the strings aren't automatically changed, but I think it's the cleanest approach.
Or you can extract this method to some strategy object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.
Okay, so here we have two things that are being mixed. First thing, is when you need to mark something to be used only on test, which I agree with #JB Nizet, using the guava annotation would be good.
A different thing, is to test private methods. Why should you test private methods from the outside? I mean.. You should be able to test the object by their public methods, and at the end that its behavior. At least, that we are doing and trying to teach to junior developers, that always try to test private methods (as a good practice).
I am not aware of any such annotation, however the following may be of value: unit testing private methods
or the following: JMockit
You can't do this, since then how could you even compile your tests? The compiler won't take the annotation into account.
There are two general approaches to this
The first is to use reflection to access the methods anyway
The second is to use package-private instead of private, then have your tests in the same package (but in a different module). They will essentially be private to other code, but your tests will still be able to access them.
Of course, if you do black-box testing, you shouldn't be accessing the private members anyway.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}
It provides a syntax like :
Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();
The only thing you have to do to create the BoundBox class is to write #BoundBox(boundClass=Outer.class) and the BoundBoxOfOuter class will be instantly generated.
As much as I know there is no annotation like this. The best way is to use reflection as some of the others suggested. Look at this post:
How do I test a class that has private methods, fields or inner classes?
You should only watch out on testing the exception outcome of the method. For example: if u expect an IllegalArgumentException, but instead you'll get "null" (Class:java.lang.reflect.InvocationTargetException).
A colegue of mine proposed using the powermock framework for these situations, but I haven't tested it yet, so no idea what exactly it can do. Although I have used the Mockito framework that it is based upon and thats a good framework too (but I think doesn't solve the private method exception issue).
It's a great idea though having the #PublicForTests annotation.
Cheers!
I just put the test in the class itself by making it an inner class:
https://rogerkeays.com/how-to-unit-test-private-methods

Categories

Resources