Junit测试中如何实例化class里面的对象被测试是一个抽象class?

how to instantiate objects inside the class to be tested is an abstract class in Junit testing?

下面有一个class,我想为其编写单元测试

abstract class ProductImpl{
   @Inject DataServices ds; // using Guice 

   public Response parse(String key, Long value){
      Response res = ds.getResponseObject(); // Response object is created using DataServices object
      res.id = key;
      res.code = value;

   }
}

我有一个测试如下

class ProductImplTest{

@InjectMocks ProductImpl impl;
Map<String, Long> map;

@Before
 map.put("abc", 10L);
 map.put("xyz", 11L);
}

@Test
public void test(){
  for(String key: map.keySet()){
    Response res = impl.parse(key, map.get(key));
    // and check if fields of Response object are set correctly i.e res.id is abc and value is 10L
  }
}

但是当我调试测试并控制转到解析方法时,DataServices 对象 ds 为空。如何通过 test 实例化这个对象。我不想使用模拟,我想要创建真正的响应对象并测试其中设置的值。

你可以使用 Mockito

@RunWith(MockitoJUnitRunner.class)
class ProductImplTest {
    @Mock DataService dService;
    @InjectMocks ProductImpl sut;

    @Test
    public void test() {
        ResponseObject ro = new ResponseObject();

        String string = "string";
        Long longVal = Long.valueOf(123);

        sut.parse("string", longVal);

        verify(dService).getResponseObject();
        assertThat(ro.getId()).isEqualTo("string");
        // you should use setters (ie setId()), then you can mock the ResponseObject and use
        // verify(ro).setId("string");
    }
}

编辑:

如果 ResponseObject 是一个抽象的 class 或者最好是一个接口,您将拥有

interface ResponseObject {
    void setId(String id);
    String getId();
    // same for code
}

在你的测试中

@Test public void test() {
    ResponseObject ro = mock(ResponseObject.class);
    // ... same as above, but
    verify(dService).getResponseObject();
    verify(ro).setId("string"); // no need to test getId for a mock
}

尝试使用构造函数注入:

class ProductImpl{
   DataServices ds;

   @Inject 
   public ProductImpl(DataServices ds) {
     this.ds = ds;
   }
}