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

查看:708
本文介绍了将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仅创建一个对象,因此字段的状态在@Test s之间共享
  • 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天全站免登陆