Spring Boot :如何使用自动布线测试使用gson对象的类

vecaoik1  于 2022-11-23  发布在  Spring
关注(0)|答案(2)|浏览(171)

我是JUnit和java中的单元测试的新手。我在测试我的代码时遇到了一个问题。任何帮助都将不胜感激。
我的java类:AService.java

@Service
public class AService {

    @Autowired
    private ServiceB serviceB;

    @Autowired
    private Gson gson;

    public MyEntity getEntity() {
        String jsonResponse = serviceB.getResponse();
        return gson.fromJson(jsonResponse, MyEntity.class);
    }
}

我的测试类:AServiceTest.java

@ExtendWith(MockitoExtension.class)
public class AServiceTest {

    @Mock
    private ServiceB serviceB;

    @Autowired
    private Gson gson;

    @InjectMocks
    private AService aService;

    @Test
    public void getEntityTest() {
        String serviceBResponse = "{\"id\":55,\"name\":\"My entity\",\"address\":\"XYZ\"}";
        when(serviceB.getResponse()).thenReturn(serviceBResponse);

        MyEntity entity = aService.getEntity();
        assertEquals("My entity", entity.getName());
    }
}

由于gson对象未被初始化,这将引发NullPointerException。此外,我们不能将gson模拟为Gson类是final
我如何测试这段代码。我正在使用spring Boot junit5。

lp0sw83n

lp0sw83n1#

我不建议模仿Gson,相反,您可以使用RefelectionUtils创建和设置Gson对象,并模仿其他依赖项服务

@ExtendWith(MockitoExtension.class)
public class AServiceTest {

   private ServiceB serviceB = Mocktio.mock(ServiceB.class);

   private Gson gson = new GsonBuilder().create();

  
   private AService aService = new AService();

   @Before
   public void setup() {
     ReflectionTestUtils.setField(aService, "serviceB", serviceB);
     ReflectionTestUtils.setField(aService, "gson", gson);
  }

   @Test
   public void getEntityTest() {
    String serviceBResponse = "{\"id\":55,\"name\":\"My entity\",\"address\":\"XYZ\"}";

    when(serviceB.getResponse()).thenReturn(serviceBResponse);
  
    MyEntity entity = aService.getEntity();
    assertEquals("My entity", entity.getName());
  }
}
brqmpdu1

brqmpdu12#

更好的可测试性方法是将Gson对象传递给服务的构造函数(即constructor dependency injection):

private ServiceB serviceB;

private Gson gson;

@Autowired
AService(ServiceB serviceB, Gson gson) {
    this.serviceB = serviceB;
    this.gson = gson;
}

Spring仍然会使用GsonAutoConfiguration配置类正常地注入Gson对象,但是在您的测试中,您现在可以使用常规的Gson对象来构造AService

AService aService = new AService(serviceB, new GsonBuilder().create());

注意:我使用new GsonBuilder().create()创建Gson对象,因为GsonAutoConfiguration就是这样将其注入生产环境的。但是,您也可以使用new Gson()创建它:

AService aService = new AService(serviceB, new Gson());

相关问题