For example I have the following classes below:
public class TesteEstatico {
public static String teste(){
return "FOO";
}
}
And I have a class that uses her method:
public class UsaTesteEstatico {
public String metodoParaTeste1 (){
return TesteEstatico.teste() " BAR ";
}
public String metodoParaTeste2 (){
return "FOO " TesteEstatico.teste() " BAR ";
}
}
Test class:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class) public class UsaTesteEstaticoTest {
@InjectMocks
UsaTesteEstatico usaTesteEstatico;
@Test
void teste1(){
Mockito.mockStatic(TesteEstatico.class);
Mockito.when(TesteEstatico.teste())
.thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
@Test
void teste2(){
Mockito.mockStatic(TesteEstatico.class);
Mockito.when(TesteEstatico.teste())
.thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
Error I get when trying to run the tests:
org.mockito.exceptions.base.MockitoException: For TesteEstatico, static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered
Versions of the libs that are in the project:
- junit-jupiter 5.5.2
- mockito-junit-jupiter 3.2.14
- mockito-inline 3.2.14
Any idea how to solve this, i've tried a few things but nothing successful.
NOTE: I cannot change or add any new libraries as it is a restricted project.
CodePudding user response:
You should use try-with-resources block in each of the tests to close the mockStatic.
public class UsaTesteEstaticoTest {
UsaTesteEstatico usaTesteEstatico = new UsaTesteEstatico();
@Test
void teste1(){
try (var ms = Mockito.mockStatic(TesteEstatico.class)) {
Mockito.when(TesteEstatico.teste()).thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
}
@Test
void teste2(){
try (var ms = Mockito.mockStatic(TesteEstatico.class)) {
Mockito.when(TesteEstatico.teste()).thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
}
Note on mockStatic in @BeforeAll
Using @BeforeAll is a trap and bad advice.
You should strive for independent tests that don't affect each other.
This is not the case for mockStatic called in @BeforeAll, as stubbing from test methods outlive the test methods.
For example
// BAD CODE DONT USE
public class UsaTesteEstaticoTest {
UsaTesteEstatico usaTesteEstatico = new UsaTesteEstatico();
static MockedStatic<TesteEstatico> ms;
@BeforeAll
public static void init() {
ms = Mockito.mockStatic(TesteEstatico.class);
}
@AfterAll
public static void close() {
ms.close();
}
@Test
void teste1() {
Mockito.when(TesteEstatico.teste()).thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
@Test
void teste2() {
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
teste2 prints:
FOO BANANA BARif run afterteste1FOO null BARif run separately
This is precisely what you want to avoid.
CodePudding user response:
you need to use static block to mock it.
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class UsaTesteEstaticoTest {
@InjectMocks
UsaTesteEstatico usaTesteEstatico;
@BeforeAll
public static void init(){
Mockito.mockStatic(TesteEstatico.class);
}
@Test
void teste1(){
Mockito.when(TesteEstatico.teste())
.thenReturn("BANANA");
String res = usaTesteEstatico.metodoParaTeste1();
System.out.println(res);
}
@Test
void teste2(){
Mockito.when(TesteEstatico.teste())
.thenReturn("LARANJA");
String res = usaTesteEstatico.metodoParaTeste2();
System.out.println(res);
}
}
