如何使用JUnit 5模拟Spring依赖关系?

时间:2019-05-20 11:03:29

标签: java junit mockito wicket junit5

我们必须测试课程,请参阅下文。我们的问题是如何填充依赖项,以便我们可以测试下面看到的原始类。

public class FragenAntwortenDataprovider extends SortableDataProvider<FragenAntworten, String> {

    @SpringBean
    private IFragenAntwortenService service;

    private IModel<FragenAntworten> filter;


    public FragenAntwortenDataprovider(IModel<FragenAntworten> filter){
        this.filter = filter;
        Injector.get().inject(this);
        setSort("id", SortOrder.DESCENDING);  // absteigend sortieren
    }


    @Override
    public Iterator<? extends FragenAntworten> iterator(long first, long count){
        List<FragenAntworten> list = load();
        List<FragenAntworten> sublist = list.subList((int) first, (int) (first+count));
        return sublist.iterator();
    }

    @Override
    public long size() {return getListSize();}

    @Override
    public IModel<FragenAntworten> model(FragenAntworten object) {
        return Model.of(object);
    }

    private void sort(final List<FragenAntworten> list){

    }

    private long getListSize(){
        List<FragenAntworten> list = service.ladeAlle(filter.getObject().getSystem());
        return list.size();
    }


    private List<FragenAntworten> load(){
        List<FragenAntworten> list = service.ladeAlle(filter.getObject().getSystem());
        return list;
    }

}

2 个答案:

答案 0 :(得分:0)

由于使用了Spring,因此可以使用其ReflectionUtils帮助类来注入依赖项:

IFragenAntwortenService service = mock(IFragenAntwortenService.class);
IModel<FragenAntworten> model = ...;
FragenAntwortenDataprovider provider = new FragenAntwortenDataprovider(model);
Field serviceField = ReflectionUtils.findField("service", provider);
ReflectionUtils.setField(serviceField, provider, service);

另一种选择是为service字段引入程序包专用的setter并避免使用反射。

答案 1 :(得分:0)

您应该让原始类的依赖项注入@Autowired@Inject。实际上,您不应使用字段注入,而应使用构造函数注入。然后,应将@ExtendWith(MockitoExtension.class)用于JUnit 5测试类。您必须将每个依赖项定义为@Mock,对于要测试的类,请使用@InjectMocks批注。

这是要使用的构造函数注入:

public class FragenAntwortenDataprovider extends SortableDataProvider<FragenAntworten, String> {

    private IFragenAntwortenService service;

    private IModel<FragenAntworten> filter;

    @Inject
    public FragenAntwortenDataprovider(IFragenAntwortenService service, IModel<FragenAntworten> filter){
        this.service = service;
        this.filter = filter;
        //I guess you don't need the injector anymore
        //Injector.get().inject(this);
        setSort("id", SortOrder.DESCENDING);  // absteigend sortieren
    }
    //Rest of class
}

然后这是一个测试类:

@ExtendWith(MockitoExtension.class)
public class testClass() {
    @Mock
    private IFragenAntwortenService service;

    @Mock
    private IModel<FragenAntworten> filter;

    @InjectMocks
    FragenAntwortenDataprovider sut; //System under Test

    @Test
    void test() {
        //Testcode
        // Control the mock with 
        when(service.anymethod()).thenReturn(result);

        var result = sut.callMethodToTest();

        // verify all calls
        verify(service, times(1)).anymethod();

        // and assert
        assertNotNull(result);
    }
}