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);