使用Mockito在内部使用通用方法模拟服务

时间:2018-11-27 14:01:41

标签: java generics junit mockito

假设我有这个存储库

@Repository public class GenericHistoryRepositoryImpl implements GenericHistoryRepository {

    @Autowired  private MongoTemplate mongoTemplate;
            @Override   public Historiable create(Historiable historiableObject, String collectionName) {
                mongoTemplate.save(historiableObject, collectionName);
                return historiableObject;   }


    @Override   public <T extends Historiable> T get(String id, Class<T> collectionClass, String collectionName) {
                Query query = new Query();
    query.addCriteria(Criteria.where("id").is(id));
    return mongoTemplate.findOne(query, collectionClass, collectionName);
            } }

我有测试要模拟存储库,但是我不知道怎么做

@RunWith(MockitoJUnitRunner.class)
public class GenericHistoryServiceTest {

    @Mock
    private GenericHistoryRepository genericHistoryRepository;

    @InjectMocks
    private GenericHistoryService genericHistoryService = new GenericHistoryServiceImpl();



    @Test   
        public <T extends Historiable> void getHistoryOk2() throws NotFoundException, ClassNotFoundException {
            String id = "1"

;
        String collectionName = HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST;
        ShipmentRequest a = mock(ShipmentRequest.class);
        Class<? extends Historiable> clazz = ShipmentRequest.class;
    when(genericHistoryRepository.get(any(String.class), eq(clazz), collectionName)).thenReturn(createExample());


        HistoriableDTO result = genericHistoryService.get(id, HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST);

        //      verify(genericHistoryRepository, times(1)).get(id, any(), HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST);

        assertThat(result, is(notNullValue()));          
        assertThat(result.getId(), is(notNullValue()));
    }

请记住,Historiable是一个抽象类

public abstract class Historiable {

    public abstract String getParentId();

}

这扩展了Historiable

@Document(collection = HistoriableCollections.HISTORIABLE_SHIPMENT_REQUEST)
public class ShipmentRequest extends Historiable {

    private String id;

    @Indexed
    private String parentId;

...

}

我的问题是“ when”一词定义了存储库模拟的行为。它具有我不知道如何模拟的通用方法

Class<? extends Historiable> clazz = ShipmentRequest.class;
    when(genericHistoryRepository.get(any(String.class), eq(clazz), collectionName)).thenReturn(createExample());

我要

类型为OngoingStubbing的thenReturn(capture#1-of?扩展Historiable)方法不适用于参数(ShipmentRequest)

private ShipmentRequest createExample() {
        ShipmentRequest history = new ShipmentRequest();
        history.setId("1");

        return history;
    }

2 个答案:

答案 0 :(得分:1)

您的when子句是问题。

您应在when内定义匹配的时间,然后声明要返回的内容。

您的when语句从开始就很好,它表明您想匹配作为第一个参数传递的任何String,但是作为第二个参数,您传递的是模拟,因此这意味着只有在特定的模拟作为第二个论点(我认为这没有发生)。

您可以将第二个参数更改为:any(Class.class)

对于第三个参数,您可以使用以下命令声明其等于collectionNameorg.mockito.ArgumentMatchers#eq(T)

答案 1 :(得分:0)

在测试课中,您可以有类似的内容

public class TestClass {

@Mock
GenericHistoryRepository genericHistoryRepository;

@InjectMock
MongoTemplate  mongoTemplate;


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

}

@InjectMock将注入模拟的行为。