使用Mockito和TestNG

ber*_*olo 5 testng spring unit-testing mockito

我使用Mockito为JUnit编写了一个工作测试,并尝试使其适应TestNG,但奇怪的是使用TestNG只有一个测试可行.

我认为它与模拟器的重置有某种关系,但是我试图调用Mockito.reset并使用BeforeMethod和BeforeClass以及不同的组合,但仍然只能通过一个测试.

我需要做些什么来让测试工作?

@BeforeClass
public void setUp() {       
    MockitoAnnotations.initMocks(this);                                
    mockMvc = MockMvcBuilders.standaloneSetup(calculatorController).build();
}

@AfterMethod
public void reset() {
    Mockito.reset(calculatorService);
}

@Test
public void addFunctionTest() throws Exception {             
    Assert.assertNotNull(calculatorController);
     Result expectedResult = new Result();
     expectedResult.setResult(10);

    when(calculatorService.add(anyInt(), anyInt())).thenReturn(expectedResult);                             

    mockMvc.perform(get("/calculator/add").accept(MediaType.APPLICATION_JSON_VALUE)
            .param("val1", "100")
            .param("val2", "100"))  
    .andExpect(content().contentType("application/json"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.result", equalTo(10)));    

    verify(calculatorService, times(1)).add(anyInt(), anyInt());
}   

@Test
public void subtractFunctionTest() throws Exception {            
    Assert.assertNotNull(calculatorController);
    Result expectedResult = new Result();
    expectedResult.setResult(90);

    when(calculatorService.subtract(anyInt(), anyInt())).thenReturn(expectedResult);                                

    mockMvc.perform(get("/calculator/subtract").accept(MediaType.APPLICATION_JSON_VALUE)
    .param("val1", "100")
    .param("val2", "10"))  
    .andExpect(content().contentType("application/json"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.result", equalTo(90)));    

    verify(calculatorService, times(1)).subtract(anyInt(), anyInt());
}
Run Code Online (Sandbox Code Playgroud)

对于未设置内容类型或预期结果错误的断言,第二个测试似乎总是失败.

似乎第一次测试的响应在某种程度上在第二次测试中被评估,因此显然是错误的!

我知道控制器和服务按预期工作,并且使用jUnit运行的完全相同的测试实际上工作正常.

我设法让测试只有在我执行以下操作时才能正常执行:

 @BeforeGroups("subtract")
 public void reset() {      
    Mockito.reset(calculatorService);
    mockMvc =       MockMvcBuilders.standaloneSetup(calculatorController).build();
 }

 @Test(groups = "subtract")
 public void subtractFunctionTest() throws Exception {    
    System.out.println("***** IN METHOD *****");
    Assert.assertNotNull(calculatorController);
    Result expectedResult = new Result();
    expectedResult.setResult(90);

    when(calculatorService.subtract(anyInt(), anyInt())).thenReturn(expectedResult);                                

    //Perform HTTP Get for the homepage
    mockMvc.perform(get("/calculator/subtract").accept(MediaType.APPLICATION_JSON_VALUE)
    .param("val1", "100")
    .param("val2", "10"))  
    .andExpect(content().contentType("application/json"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.result", equalTo(90)));    

    //Verify that the service method was only called one time
    verify(calculatorService, times(1)).subtract(anyInt(), anyInt());
}
Run Code Online (Sandbox Code Playgroud)

这意味着我需要为每个测试方法添加其中一种重置方法,然后我需要一组每个测试方法看起来不正确.

Sta*_*sev 8

这些框架的行为有所不同:

  • JUnit为其每个测试方法创建一个新的类实例.这意味着测试之间不共享字段.
  • 但TestNG只创建一个对象,因此字段中的状态在@Tests 之间共享

对于Mockito,您需要在每个测试方法之前初始化模拟,以便@Test在TestNG中的两个s 之间不共享状态:

@BeforeMethod
public void init() {
    MockitoAnnotations.initMocks(this);
}
Run Code Online (Sandbox Code Playgroud)

对于JUnit,它可以在盒子外工作,因为2nd @Test有自己的字段和自己的模拟.

  • 对我来说,它与 `@BeforeMethod` 一起工作,并将用 `@InjectMocks` 注释的实例设置为 `null` *before* `initMocks()` 的调用。见//见https://code.google.com/archive/p/mockito/issues/304 (3认同)