Unit testing with mockito for constructors
Once again the problem with unit-testing comes from manually creating objects using new
operator. Consider passing already created Second
instead:
class First {
private Second second;
public First(int num, Second second) {
this.second = second;
this.num = num;
}
// some other methods...
}
I know this might mean major rewrite of your API, but there is no other way. Also this class doesn't have any sense:
Mockito.when(new Second(any(String.class).thenReturn(null)));
First of all Mockito can only mock methods, not constructors. Secondly, even if you could mock constructor, you are mocking constructor of just created object and never really doing anything with that object.
Mockito: how to test that a constructor was called?
This can't be done with Mockito, since the object being created is not a mocked object. This also means that you won't be able to verify anything on that new object either.
I've worked around this scenario in the past by using a Factory
to create the object rather than newing it up. You're then able to mock the Factory
to return the object required for your test.
Whether you're happy changing your design to suit your tests is up to you!
Mock a constructor with parameter
The code you posted works for me with the latest version of Mockito and Powermockito. Maybe you haven't prepared A?
Try this:
A.java
public class A {
private final String test;
public A(String test) {
this.test = test;
}
public String check() {
return "checked " + this.test;
}
}
MockA.java
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class MockA {
@Test
public void test_not_mocked() throws Throwable {
assertThat(new A("random string").check(), equalTo("checked random string"));
}
@Test
public void test_mocked() throws Throwable {
A a = mock(A.class);
when(a.check()).thenReturn("test");
PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a);
assertThat(new A("random string").check(), equalTo("test"));
}
}
Both tests should pass with mockito 1.9.0, powermockito 1.4.12 and junit 4.8.2
Mock constructor with mockito
UPDATE: since since version 3.5.0, Mockito can do this without PowerMockito.
You can use PowerMock to mock constructors.
If you can't use PowerMock for some reason, the most workable solution is to inject a factory to whatever class contains this method. You would then use the factory to create your GeneraIDParaEntidadCliente
object and mock the factory.
Mock static method called from constructor in java class
So to answer your question how to mock a static method: mockito allows this since version 3.8.0. You can find a tutorial here at Baeldung
This allows generating a statically mocked Object for a concrete context, which you can create within a try block. For your case this would look like the following.
Fixed Unit Test
package com.javaeasily.demos.junit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class MyClassTest {
private MyClass myclass;
@BeforeEach
public void SetUp() {
try (MockedStatic<NodeUtils> nodeUtilsMockedStatic = Mockito.mockStatic(NodeUtils.class)) {
nodeUtilsMockedStatic.when(NodeUtils::getMyNode).thenReturn("foo");
myclass = new MyClass();
}
}
@Test
public void testReconfigureNode() {
myclass.reconfigureNode();
}
}
Mockito dependency
You need mockito with at least version 3.8.0 in your project.
With maven add:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
With gradle add:
testImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.8.0'
Related Topics
How to Determine the Primitive Type of a Primitive Variable
How to Convert a Java Object to Xml with Open Source APIs
Why Is Method Overloading and Overriding Needed in Java
How to Set Order of Repositories in Maven Settings.Xml
Convert Xml to Java Object Using Jaxb (Unmarshal)
Understanding the etc/Gmt Time Zone
Create Simple Pojo Classes (Bytecode) at Runtime (Dynamically)
Why Catch Exceptions in Java, When You Can Catch Throwables
In Java How to Re-Open System.In After Closing It
Rejectedexecutionexception Inside Single Executor Service
Getting Class Cast Exception Where Both Classes Are Exactly the Same
Accessing Kotlin Extension Functions from Java
How to Save User Settings in Java Application
How to Set Eclipse Console Locale/Language
Displaying Am and Pm in Lower Case After Date Formatting