【问题标题】:Method not getting mocked方法没有被嘲笑
【发布时间】:2018-09-17 14:36:47
【问题描述】:

我正在使用 Mockito 来模拟一个方法,但测试正在运行真正的方法。

//Controller
@RestController
public class Controller {

    private Utils utils = new Utils();

    public String myMethod(String json){

        // Stuff gets done
        return utils.writeToKafka(topic, json, kafkatemplate, classname);

    }

我有一个如下所示的测试类:

//Test
@RunWith(SpringJUnit4ClassRunner.class)
public class ControllerTest {

    @Captor
    ArgumentCaptor<String> argumentCaptor;

    @Test
    public void processOSPUpdateRequested_test(){
         Controller controller = new Controller();
         Utils utils = Mockito.spy(new Utils());
         Mockito.doReturn("myResult").when(utils).writeToKafka(anyString(), anyString(), any(), anyString());

         String topic = controller.myMethod(myString);

         //Some assertions

我的 writeToKafka 方法签名是:

public String writeToKafka(String topic, String json, KafkaTemplate<String, String> kafkaTemplate, String classname)

但是,当我运行测试时,writeTokafka 没有被嘲笑!它运行实际的方法。为什么会这样?我错过了什么?

【问题讨论】:

  • 您的控制器有自己的utils 实例。它没有你发现的那个。
  • @khelwood 那么这里的好做法是什么?使用单例模式?
  • 依赖注入常用于解决此类问题。通常你不会让你的控制器实例化 Utils 本身:它会从你可以访问的地方获取它,以便你可以替换它。

标签: java unit-testing testing mocking mockito


【解决方案1】:

问题的症结所在:您是 newUtils 的一个实例,而您无法从测试中完全找到它。

有两种方法可以解决这个问题 - 两种方法都来自关于是否要使用模拟的哲学立场。两者都要求你注入Utils并在某处把它变成一个bean。

  1. 注入 Utils 并在您的测试中注入模拟,然后放弃 Spring 测试运行器。

    一旦你有了模拟,你会想要改变你的测试,使用 Spring 运行器,而是使用 Mockito 运行器。

    @RunWith(MockitoJUnitRunner.class)
    public class ControllerTest {
        @Mock
        private Utils utils;
    
        @InjectMocks
        private Controller testObj;
    
        // The rest of your test code
    }
    
  2. Utils 作为已定义的测试范围 bean 注入到您的测试中,该 bean 表现出您希望在测试下的行为。

    这有点复杂,但是您可以利用 Spring 测试运行器。我把这个作为练习留给读者(基本上,一旦你写了Utils bean,再写一个用于测试就不难了)。

【讨论】:

    猜你喜欢
    • 2019-07-21
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2018-12-24
    相关资源
    最近更新 更多