This question already has answers here:
How to mock constructor with PowerMockito
(1 answer)
Mock a constructor with parameter
(7 answers)
Closed 2 years ago.
I have a class that's composed of other objects/dependencies as follows:
public class One{
private RedisPool redisPool;
private static final WeakHashMap<String, Dedup<String>> CACHE = new WeakHashMap<>();
private static final ObjectMapper mapper = new ObjectMapper();
private BigQueryManager bigQueryManager;
private RedisClientManager redisClientManager;
private PubSubIntegration pubSub;
public One(RedisPool redisPool, Configuration config) {
this.redisPool = redisPool;
bigQueryManager = new BigQueryManager(config);
redisClientManager = new RedisClientManager(redisPool, config);
pubSub = new PubSubIntegration(config);
}
....
...
other methods
}
I tried:
public class OneTest{
#Mock
RedisPool redisPool;
#Mock
Configuration config;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
One one = new One(redisPool, config);
}
}
But I'm not sure whether the objects constructed inside the constructor also get mocked, as I have used those objects in other methods inside the class.
How can I mock the objects constructed inside the constructor?
I don't think you can achieve this using Mockito alone, but you can if you also use PowerMockito.
This article gives an example that is quite similar to what you want to achieve.
Note that PowerMockitio will mess up any test coverage statistics that you are collecting.
EDIT
If the article disappears, the gist of it is that you need to annotate your Test class slightly differently
#RunWith(PowerMockRunner.class)
#PrepareForTest(One.class)
public class OneTest {
The #PrepareForTest annotation refers to the Class that you need to alter the bahaviour of - in your case the One class.
You then tell PowerMoncito to return an object you can control when a new instance is created. In your case
PowerMockito.whenNew(BigQueryManager.class)
.withAnyArguments().thenReturn(mockBigQueryManager);
Related
I need to test private method. What is the correct way of testing below method? I tried using Mockito when.. but how do I mock a private method. I think we cannot Mock private method.
private classObject privateMethod(Message message){
try{
Objectmapper mapper = new ObjectMapper();
return mapper.readValue(message.getBody(), ClassName.class);
}catch(){
throw new Exception();
}
}
//I am getting an exception while testing
byte[] body = {10,-11,12,14,15};
MessageProperties msgProp = new MessageProperties();
Message message = new Message(body, msgProp);
// the above message is passed as parameter to function through
// which private method is called
objectxyz.execute(message);
// execute method
public void execute(Message message){
objectxyz xyz = privateMethod(message);
objectabc abc = service.someMethod(xyz);
List<object> list = someAnotherMethod(abc, xyz);
}
// I tried below code in my test case and have used
// #Mock private ObjectMapper objectMapper;
Mockito.when(objectMapper.readValue(body, ClassName.class)).thenReturn(classObject);
Spring boot has nothing special about it:
Private methods should not be tested - it's an internal "how" of the class and you should mainly test the API of the class - the "capabilities" that it exposes to the user of the class via non-private methods.
Consider treat a class as a black box (with possibly mocked dependencies of this class) and check its functionality as I've explained.
You can use the manifold framework to test with reflection. See this previously answered solution: How do I test a private function or a class that has private methods, fields or inner classes?
These are Basic basic approaches to test private methods.
Don't test private methods.
Give the methods package access.
Use a nested test class.
Use reflection.
Detail article
yup, private method should be a internal method, should use by another public method, so. do not test it;
Is the feature provided by Mockito 2 to mock final methods and final classes using org.mockito.plugins.MockMaker(mock-maker-inline) generally available(released) or still in the incubation phase. I am using mockito-core-2.23.4 artifact in my application. Need suggestions in mocking the final classes and methods. Is it advisable to use this approach or look for alternate options?
As of Mockito 2.x, Mockito now supports mocking of final classes and methods.
Example:
Say we have a MyList class shown below as the collaborator in test cases.
We’ll add a new finalMethod to this class:
public class MyList extends AbstractList {
final public int finalMethod() {
return 0;
}
}
And we'll also extend it with a final subclass:
public final class FinalList extends MyList {
#Override
public int size() {
return 1;
}
}
Before Mockito can be used for mocking final classes and methods, it needs to be configured.
We need to add a text file to the project's src/test/resources/mockito-extensions directory named org.mockito.plugins.MockMaker and add a single line of text:
mock-maker-inline
Mockito checks the extensions directory for configuration files when it is loaded. This file enables the mocking of final methods and classes.
Mock a Final Method:
Once Mockito is properly configured, a final method can be mocked like any other:
#Test
public void whenMockFinalMethodMockWorks() {
MyList myList = new MyList();
MyList mock = mock(MyList.class);
when(mock.finalMethod()).thenReturn(1);
assertNotEquals(mock.finalMethod(), myList.finalMethod());
}
By creating a concrete instance and a mock instance of MyList, we can compare the values returned by both versions of finalMethod() and verify that the mock is called.
Mock a Final Class:
Mocking a final class is just as easy as mocking any other class:
#Test
public void whenMockFinalClassMockWorks() {
FinalList finalList = new FinalList();
FinalList mock = mock(FinalList.class);
when(mock.size()).thenReturn(2);
assertNotEquals(mock.size(), finalList.size());
}
Similar to the test above, we create a concrete instance and a mock instance of our final class, mock a method and verify that the mocked instance behaves differently.
Reference: https://www.baeldung.com/mockito-final
This question already has answers here:
JUnit: using constructor instead of #Before
(8 answers)
Closed 5 years ago.
Using Junit 4.12. JUnit's Before annotation is documented, but it seems to me that it is no longer needed. Apparently JUnit creates a new instance for every test, as shown in the following snippet:
import org.junit.Test;
public class BeforeTest {
TestObject testObject = new TestObject();
#Test
public void one(){
System.out.println(testObject.status);
testObject.setStatus("Used by one()");
}
#Test
public void two(){
System.out.println(testObject.status);
testObject.setStatus("Used by two()");
}
private class TestObject{
public String status;
public TestObject(){
status = "new";
}
void setStatus(String newStatus){status = newStatus;}
}
}
-----------------------------
new
new
Do we still need #Before?
As in this similar question, methods annotated with #Before can usually be replaced with constructors / field initialization.
Some subtle differences exist that may make a difference in corner cases:
Exception Handling: Exceptions in #Before cause #After to be called, exceptions in constructor do not
Subclass initialization: #Before is called after the constructor has completed, allowing to access anything produced by child-class constructors
Subclassing: With #Before you can override parent class #Before methods, with constructors you always need to call one of the parent class constructors.
#Rule: The constructor is called before #Rule methods, #Before is called after #Rule methods
This question already has answers here:
What are static factory methods?
(14 answers)
Closed 5 years ago.
Most of my experience with Java has been in the classroom setting, editing my own code. I'm finally venturing into the exciting world of deciphering other people's code, and I'm wondering about this:
public class MyClass {
// Some fields here
// A constructor there
// Setters and getters abound
public static MyClass create() {
return new MyClass();
}
}
I'm wondering what the purpose of this method is. It doesn't seem like more trouble to write MyClass foo = new MyClass(); than to write MyClass foo = MyClass.create();. Is this some kind of Java idiom I'm unaware of? Is it completely unnecessary? Would it perhaps be somehow more useful in a class where the constructor took any parameters? What's the deal?
Thanks!
It's a very useful idiom, static factory method. It gives full control on the new instance creation, whether it's a different instance, a cached instance etc. It only makes sense if the constructor is set to private.
public class MyClass {
private MyClass() {}
public static MyClass create() {
return new MyOtherClass();
}
private static class MyOtherClass extends MyClass {
...
}
}
Static factory method.
The constructor is normally private, that way the creation of new objects can be controlled by one method.
Further reading static builder class.
I am writing some JUnit tests for legacy code and I am a big fan of using annotations. I would like to know if it is possible to create a declaration to a spied object and later instantiate it. The reason I ask is because I have a class with a non-null constructor. The values for this constructor are not known until after setup of the test cases. The code below shows what I would like to do:
#RunWith(MockitoJUnitRunner.class)
public class ObjectUndertestTest {
#Spy private SomeClassToSpy someClassToSpy;
private Integer parameterOne;
private Integer parameterTwo;
#Before
public void setupTest() {
parameterOne = 1;
parameterTwo = 2;
someClassToSpy = new SomeClassToSpy(parameterOne, parameterTwo);
}
}
The only way that I can see to be able to do this is to mix my syntax and use the traditional spy(object to mock) notation. That is:
#RunWith(MockitoJUnitRunner.class)
public class ObjectUndertestTest {
private SomeClassToSpy someClassToSpy;
private Integer parameterOne;
private Integer parameterTwo;
#Before
public void setupTest() {
parameterOne = 1;
parameterTwo = 2;
someClassToSpy = new SomeClassToSpy(parameterOne, parameterTwo);
SomeClassToSpy spySomeClassToSpy spy(someClassToSpy);
}
}
Or something similar. Any thoughts on this?
Beware that #Spy isn't really a documentation annotation: It is an instruction for MockitoJUnitRunner (et al) to initialize the spy automatically for you according to its documented usage patterns. Though annotations are useful and informative, I think it may cause more confusion to use the annotation for its name and not its semantics.
That said, if it's just a matter of constructing an instance with your chosen constructor arguments, you can call the constructor directly and explicitly and use Mockito's initialization to wrap it in a spy (as in the #Spy docs):
#Spy private SomeClassToSpy someClassToSpy = new SomeClassToSpy(1, 2);
Though you'd be right to favor #Before methods over class initializers or constructors, this is an explicitly-documented method of initialization and one unlikely to cause test pollution or initialization-order problems.