【问题标题】:Mock constructor of a class类的模拟构造函数
【发布时间】:2019-05-22 05:16:36
【问题描述】:

我正在为我的 java 类编写测试类。我正在将 Junit5 与 Mockito 一起使用。

我正在使用与 Power Mockito 不兼容的 Junit5,所以我只使用 Mockito。

我有class Emp,它具有如下所示的函数findSalary,EmpProfileClient 在构造函数中被初始化。

Class Emp {

......

  public void findSalary(empId) {

    ...

    TaxReturn taxReturn = new TaxReturn(EmpProfileClient);

    int value = taxReturn.apply(new TaxReturnRequest.withEmpId(empId))

                    .returnInRupee();

    ...

  }

}

当我编写测试用例时,我模拟了EmpProfileClient,但由于我们在一个方法中创建TaxReturn,我如何模拟TaxReturn.apply,所以我可以编写期望以根据我的选择获得值我在测试类中设置了什么?

【问题讨论】:

  • 那么问题是什么?
  • 添加一个间接层。而不是调用构造函数注入产生 TaxReturns 的工厂。
  • 问题是在测试findSalary之前如何写期望。
  • 你要测试什么?我的意思是哪种方法?你想模拟findSallary里面的所有东西吗?
  • 或仅taxReturn.apply 调用?

标签: mockito junit5


【解决方案1】:

如果你想模拟这个,TaxReturn 类应该是Emp 类中的注入 bean。添加一个注入框架(如 Spring)并注入 TaxReturn 类。在您编写的测试中,您可以注入一个 Mock 而不是真正的类。请参阅 mockito 框架的 @InjectMocks 注释。

【讨论】:

    【解决方案2】:

    如果我正确理解了您的问题(您正在寻找嘲笑taxReturn.apply),我建议接下来:

    首先。重构您的 taxReturn 实例化(因为与尝试模拟局部变量相比,模拟方法行为要容易得多)

    public class EmpService {
    
     public int findSalary(Integer empId) {
      //...
      // It's doesn't matter what the actual empProfileClient type is
      // as you mocking creation behavior anyway  
      Object empProfileClient = null;
      TaxReturn taxReturn = createClient(empProfileClient);   
      int value = taxReturn.apply(new TaxReturnRequest().withEmpId(empId))
       .returnInRupee();
      //...
      return value; // or whatever 
     }
    
     protected TaxReturn createClient(Object empProfileClient) {
      return new TaxReturn(empProfileClient);
     }
    
    }
    

    其次。在您的测试中使用 Mockito.spy():

    class EmpServiceTest {
    
      @Test
      void findSalary() {
        TaxReturn taxReturn = Mockito.mock(TaxReturn.class);
        // this is the main idea, here you using partial EmpService mock instance
        // part is mocked(createClient()) and other part(findSalary()) is tested
        EmpService service = Mockito.spy(EmpService.class);
        when(service.createClient(any())).thenReturn(taxReturn);
        when(taxReturn.apply(any(TaxReturnRequest.class))).thenReturn(taxReturn);
        int yourExpectedValue = 5;
        when(taxReturn.returnInRupee()).thenReturn(yourExpectedValue);
        assertEquals(yourExpectedValue, service.findSalary(0));
      }
    }
    

    请记住,any()、spy()、when() 和 mock() 方法是 Mockito API 的一部分。所以这里没有隐藏任何东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 2019-11-24
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 2011-11-24
      相关资源
      最近更新 更多