Mockito - thenReturn всегда возвращает нулевой объект
Я пытаюсь реализовать Mockito для тестирования определенного метода, но .thenReturn(...), кажется, всегда возвращает нулевой объект вместо того, что я намеревался:
CUT:
public class TestClassFacade {
// injected via Spring
private InterfaceBP bpService;
public void setBpService(InterfaceBP bpService) {
this.bpService = bpService;
}
public TestVO getTestData(String testString) throws Exception {
BPRequestVO bpRequestVO = new BPRequestVO();
bpRequestVO.setGroupNumber(testString) ;
bpRequestVO.setProductType("ALL") ;
bpRequestVO.setProfileType("Required - TEST") ;
IBPServiceResponse serviceResponse = bpService.getProduct(bpRequestVO); //PROBLEM
if (serviceResponse.getMessage().equalsIgnoreCase("BOB")) {
throw new Exception();
} else {
TestVO testVO = new TestVO();
}
return testVO;
}
}
Spring Конфигурация:
<bean id="testClass" class="com.foo.TestClassFacade">
<property name="bpService" ref="bpService" />
</bean>
<bean id="bpService" class="class.cloud.BPService" />
Метод тестирования Mockito:
@RunWith(MockitoJUnitRunner.class)
public class BaseTest {
@Mock BPService mockBPService;
@InjectMocks TestClassFacade mockTestClassFacade;
private String testString = null;
private BPRequestVO someBPRequestVO = new BPRequestVO();
private IBPServiceResponse invalidServiceResponse = new BPServiceResponse();
@Test (expected = Exception.class)
public void getBPData_bobStatusCode_shouldThrowException() throws Exception {
invalidServiceResponse.setMessage("BOB");
someBPRequestVO.setGroupNumber(null);
someBPRequestVO.setProductType("ALL");
someBPRequestVO.setProfileType("Required - TEST");
System.out.println("1: " + someBPRequestVO.getGroupNumber());
System.out.println("2: " + someBPRequestVO.getProductType());
System.out.println("3: " + someBPRequestVO.getProfileType());
System.out.println("4: " + someBPRequestVO.getEffectiveDate());
when(mockBPService.getProduct(someBPRequestVO)).thenReturn(invalidServiceResponse);
mockTestClassFacade.getTestData(testString);
verify(mockBPService).getProduct(someBPRequestVO);
}
}
Выход системы:
1: null
2: ALL
3: Required - TEST
4: null
Что происходит в том, что при запуске теста объект serviceResponse имеет значение NULL в строке в CUT, помеченном//ПРОБЛЕМА выше. Мое желание состоит в том, чтобы этот объект был заполнен моим объектом "invalidServiceResponse" из моего тестового метода. Судя по выводам моего System.out.println, кажется, что мой bpRequestVO соответствует моему someBPRequestVO в контенте.
Может ли кто-нибудь показать мне, что мне здесь не хватает?
Спасибо за ваше время!
Ответы
Ответ 1
Экземпляр BPRequestVO, который вы используете с when()
, отличается от экземпляра, используемого в getTestData()
.
Если вы не переопределите equals()
, они не будут совпадать.
Вам не нужно писать настраиваемый Matcher, если вы переопределите equals(). Обратите внимание на следующее из документации Mockito:
"Пользовательские аргументы могут сделать тест менее читаемым. Иногда лучше реализовать equals() для аргументов, передаваемых в mocks (Mockito, естественно, использует equals() для сопоставления аргументов). Это может сделать тестовый очиститель."
Ответ 2
Проблема заключается в использовании when()
.
Вы отправляете ссылку на построенный экземпляр; в результате, насмешка вернет то, что вы хотите, только если аргумент, переданный методу, является той же ссылкой.
То, что вы хотите, это совпадение аргументов; что-то вроде:
when(mockBPService.getProduct(argThatMatches(someBPRequestVO))
.thenReturn(whatYouWant);
Конечно, это требует, чтобы вы записывали совпадение аргументов!
Обратите внимание, что есть встроенный помощник, который может делать то, что вы хотите:
when(mockBPService.getProduct(eq(someBPRequestVO))).thenReturn(whatYouWant);
Этот сопрягатель, конечно, требует, чтобы ваш класс BPRequestVO
реализовал equals()
(и hashCode()
тоже)!
Ответ 3
Вместо создания в классе BPRequestVO метода equals вы можете создать mock-аргумент с "any (YourObject.class)" следующим образом:
when(mockBPService.getProduct(any(BPRequestVO.class))).thenReturn(invalidServiceResponse);