Spring 引导:如何使用自动装配测试使用 gson 对象的 class
Spring Boot: How to test a class which is using gson object using autowiring
我是 java 中 JUnit 和单元测试的新手。我在测试代码时遇到问题。感谢您的帮助。
我的 java class: 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);
}
}
我的测试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());
}
}
这会给出 NullPointerException,因为 gson
对象没有被初始化。我们也不能模拟 gson
因为 Gson
class 是 final
.
我如何测试这段代码。我正在使用 spring boot 和 junit5.
更好的可测试性方法是将 Gson
对象传递给服务的构造函数(即 constructor dependency injection):
private ServiceB serviceB;
private Gson gson;
@Autowired
AService(ServiceB serviceB, Gson gson) {
this.serviceB = serviceB;
this.gson = gson;
}
Spring 仍会使用 GsonAutoConfiguration
配置 class 正常注入 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());
我不建议模拟 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());
}
}
我是 java 中 JUnit 和单元测试的新手。我在测试代码时遇到问题。感谢您的帮助。
我的 java class: 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);
}
}
我的测试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());
}
}
这会给出 NullPointerException,因为 gson
对象没有被初始化。我们也不能模拟 gson
因为 Gson
class 是 final
.
我如何测试这段代码。我正在使用 spring boot 和 junit5.
更好的可测试性方法是将 Gson
对象传递给服务的构造函数(即 constructor dependency injection):
private ServiceB serviceB;
private Gson gson;
@Autowired
AService(ServiceB serviceB, Gson gson) {
this.serviceB = serviceB;
this.gson = gson;
}
Spring 仍会使用 GsonAutoConfiguration
配置 class 正常注入 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());
我不建议模拟 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());
}
}