2016-06-02 4 views
2

Я взял рабочий тест, написанный для JUnit, используя Mockito и попытался адаптировать его для работы с TestNG, но, как ни странно, с помощью TestNG будет работать только один тест.Использование Mockito с 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()); 
} 

Второй тест, как правило, не срабатывает при утверждении, что либо тип содержимого не установлен, либо ожидаемый результат является неправильным.

Кажется, что ответ на первый тест как-то оценивается во втором тесте, и, очевидно, это неправильно!

Я знаю, что контроллер и служба работают, как ожидалось, и те же самые тесты, выполняемые с 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()); 
} 

Это означает, что мне нужно добавить один из этих сброса методов для каждого метода испытаний, хотя и тогда я нужна группа за каждый метод тестирования, который не кажется правильным.

+0

Какую библиотеку вы используете для утверждений ('Результат ожидаетсяResult = new Result()')? –

+0

Вы возвращаете макет после каждого метода, но вы ничего не делаете с 'mocMvc'. Может ли это повлиять на ваши тесты? Можете ли вы проверить, что с изменением '@ BeforeClass' на' @ BeforeMethod' –

+0

Привет, Евгений, я пробовал играть и никаких комбинаций не работал. Я обновляю свой пост тем, что мне удалось получить, но это будет означать много повторений кода. – berimbolo

ответ

4

Существует разница в поведении этих структур:

  • JUnit создает новый экземпляр класса для каждого из своих методов испытаний. Это означает, что поля не разделяются между тестами.
  • Но TestNG создает только один объект и, таким образом, состояние в полях распределяется между к @Test s

Для Mockito вам необходимо инициализировать издевается перед каждым методом испытаний, так что состояние не разделяется между двумя @Test с в TestNG:

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

Для JUnit это работает из коробки, потому что второй @Test имеет свои собственные поля и свои собственные издевается.

+0

Я пробовал это, и он не работает, результаты вызовов возвращаются в неправильном порядке. Поэтому, если мой метод добавления ожидает результат 5, а мой метод вычитания ожидает результат 10, иногда мой тест добавления завершится неудачей с ошибкой утверждения, которую он получил 10 и ожидал. 5. – berimbolo

+0

Вы уверены, что используете '@ BeforeMethod', а не '@ BeforeClass'? –

+0

Я пробовал оба метода BeforeMethod и BeforeClass. Тест выполняет реальный вызов контроллера и издевается над ответом на обслуживание, поэтому я не вижу, как результаты могут быть замешаны. Единственный способ, которым я смог заставить тесты работать, состоял в том, чтобы использовать группы и давать каждому методу группу, а затем перезапускать аннотацию перед группами, но я попробую еще раз с помощью PreMethod и вернусь вскоре, потому что я звонил в Mockito .reset в аннотации AfterMethod. – berimbolo

Смежные вопросы