繁体   English   中英

Mokito/Java - Static 方法模拟

[英]Mokito/Java - Static Methods Mock

例如,我有以下课程:

public class TesteEstatico {

   public static String teste(){
      return "FOO";
   }

}

我有一个 class 使用她的方法:

public class UsaTesteEstatico {

   public String metodoParaTeste1 (){
       return  TesteEstatico.teste() + " BAR ";
   }

   public String metodoParaTeste2 (){
       return  "FOO "+TesteEstatico.teste() + " BAR ";
   }

}

测试 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);

   }
}

尝试运行测试时遇到的错误:

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

项目中的库版本:

  • junit-jupiter 5.5.2
  • mockito-junit-jupiter 3.2.14
  • 模拟内联 3.2.14

任何想法如何解决这个问题,我已经尝试了一些东西但没有成功。

注意:我不能更改或添加任何新库,因为它是一个受限制的项目。

您应该在每个测试中使用 try-with-resources 块来关闭 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);
        }
    }
}

@BeforeAll 中关于 mockStatic 的注意事项

使用@BeforeAll是一个陷阱和不好的建议。 您应该努力进行不会相互影响的独立测试。 这不是 @BeforeAll 中调用的 mockStatic 的情况,因为测试方法的存根比测试方法的寿命更长。

例如

// 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打印:

  • FOO BANANA BAR如果在teste1之后运行
  • FOO null BAR如果单独运行

这正是您要避免的。

您需要使用 static 块来模拟它。

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);

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM