有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何用JUnit5模拟Spring依赖关系?

我们必须测试类,见下文。我们的问题是如何填充依赖项,以便测试您在下面看到的原始类

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) 个答案

  1. # 1 楼答案

    因为您使用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,并避免使用反射

  2. # 2 楼答案

    您应该让原始类使用@Autowired@Inject注入依赖项。实际上,不应该使用字段注入,而应该使用构造函数注入。然后,您应该对JUnit 5测试类使用@ExtendWith(MockitoExtension.class)。必须定义为@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);
        }
    }