将 Mockito 与 TestNG 一起使用 [英] Using Mockito with TestNG

查看:36
本文介绍了将 Mockito 与 TestNG 一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I took a working test written for JUnit using Mockito and tried to adapt it to work with TestNG but oddly using TestNG only one test will work.

我认为这在某种程度上与模拟的重置有关,但我尝试调用 Mockito.reset 并使用 BeforeMethod 和 BeforeClass 以及不同的组合,但仍然只能通过一个测试.

I think it is somehow related to the resetting of the mocks but I have played around with trying to call Mockito.reset and using BeforeMethod and BeforeClass and different combinations but still can only get one test to pass.

我需要做什么才能让测试正常进行?

What I need to do to get the test to work?

@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());
}

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

The second test always seems to fail on assertions that either content type is not set or the expected result is wrong.

似乎第一个测试的响应在第二个测试中以某种方式被评估,因此显然是错误的!

It seems like the response for the first test is somehow being evaluated in the second test and so is obviously wrong!

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

I know the controller and service work as expected and the exact same tests running with jUnit actually work ok.

只有当我执行以下操作时,我才能使测试正常执行:

I have managed to get the tests to perform properly only when I do the following:

 @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());
}

这意味着我需要为每个测试方法添加这些重置方法之一,然后我需要为每个测试方法设置一个组,这似乎不正确.

This means I need to add one of these reset methods for each test method though and I then need a group per test method which doesnt seem correct.

推荐答案

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

There is a difference in the behaviour of these frameworks:

  • JUnit 为它的每个测试方法创建一个新的类实例.这意味着这些字段不会在测试之间共享.
  • 但 TestNG 只创建一个对象,因此字段中的状态在 @Tests
  • 之间共享
  • JUnit creates a new instance of class for every of its test methods. This means that the fields are not shared between tests.
  • But TestNG creates only one object and thus the state in fields is shared between to @Tests

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

For Mockito you need to init mocks before every test method so that the state is not shared between two @Tests in TestNG:

@BeforeMethod
public void init() {
    MockitoAnnotations.initMocks(this);
}

对于 JUnit,它开箱即用,因为第二个 @Test 有自己的字段和自己的模拟.

For JUnit it works out of box because 2nd @Test has its own fields and its own mocks.

这篇关于将 Mockito 与 TestNG 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆