我有以下服务类别:
@Service
public class BidServiceImpl implements BidService {
private final String apiUrl;
private final RestTemplate restTemplate;
@Autowired
public BidServiceImpl(RestTemplate restTemplate,
@Value("${api.url}") String apiUrl){
this.apiUrl = apiUrl;
this.restTemplate = restTemplate;
}
public List<Bid> findAll() {
ResponseEntity<Bid[]> responseEntity = restTemplate.getForEntity(apiUrl, Bid[].class);
Bid[] bids = responseEntity.getBody();
return Arrays.asList(bids);
}
}
以及随后的测试:
@RunWith(MockitoJUnitRunner.class)
public class TestBidService {
@InjectMocks
private BidServiceImpl bidService;
@Mock
RestTemplate restTemplate;
@Test
public void testFindAllReturnsListOfBids(){
List<Bid> b = new ArrayList<>();
Bid[] arr = new Bid[2];
arr[1] = new Bid();
arr[0] = new Bid();
ResponseEntity<Bid[]> br = new ResponseEntity<>(arr, HttpStatus.OK);
when(restTemplate.getForEntity("url",Bid[].class)).thenReturn(br);
List<Bid> bids = bidService.findAll();
Assert.assertEquals(2,bids.size());
Assert.assertTrue(bids instanceof List);
}
}
运行单元测试时,我在NullPointerException
上得到了apiUrl
。在我的服务类中作为@Value
注入。问题是为什么当我运行api并通过控制器访问该服务方法时,它无法从application.properties
中获取值,所以一切正常。
答案 0 :(得分:1)
因为所有<?php
$DBhost = "localhost";
$DBuser = "root";
$DBpass = "";
$DBname = "test";
try{
$DBcon = new PDO("mysql:host=$DBhost;dbname=$DBname",$DBuser,$DBpass);
$DBcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $ex){
die($ex->getMessage());
}
?>
,@MockitoJUnitRunner
和@InjectMocks
都是Mockito的东西,他们对Spring一无所知。因此,他们不了解@Mock
所做的事情,也不会注入其价值。在这种情况下,弹簧容器甚至不会启动。
如果您正在使用spring-boot并希望Spring注入该值,则可以考虑使用@Value
起动器并使用其spring-boot-starter-test
来配置Mockito模拟:
@MockBean
但这是一个集成测试,因为它将启动整个spring容器,因此它比真正的单元测试要慢。
如果您希望测试尽可能快地运行,请不要依赖Spring为您注入该值。只需自己设置:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestBidService {
@Autowired
private BidServiceImpl bidService;
@MockBean
RestTemplate restTemplate;
@Test
public void testFindAllReturnsListOfBids(){
///
}
}