[英]How to Test void Method with spring repository using Junit and Mockito
我有一個調用 spring 數據存儲庫的 java spring 服務,我想用 mockito 做一個 Junit 測試,這是我的類和我想測試的服務:
@Service
public class DataServiceImpl implements DataService{
@Autowired
private CautionRepository cautionRepository;
@Override
public void addCautions(List<CautionsDTO> cautions, Contrat contrat) {
if(cautions != null && !cautions.isEmpty()) {
cautions.forEach(caution -> {
Caution caution = new Caution();
cautionContrat.setAmount(caution.getAmount());
cautionContrat.setDate(caution.getDate());
caution.setContrat(contrat);
cautionRepository.save(caution);
});
}
}
}
這是我的單元測試
@RunWith(SpringRunner.class)
public class DataServiceImplTest{
@InjectMocks
private DataServiceImpl dataService;
@Mock
private CautionRepository cautionRepository;
@Test
public void addListCautionsTest() {
List<CautionsDTO> cautions = new ArrayList<>();
ContratExportation contrat = new ContratExportation();
Caution caution = new Caution();
dataDelService.addCautions(cautions,contrat);
Mockito.verify(cautionRepository, times(1)).save(caution);
}
}
當我運行測試時,出現以下錯誤:
Wanted but not invoked:
cautionRepository.save(
org.model.Caution@2abe9173
);
-> at org.service.DataServiceImplTest.addListCautionsTest(DataServiceImplTest.java:292)
Actually, there were zero interactions with this mock.
你知道我的測試有什么錯誤嗎
首先,您忘記將注意對象添加到注意列表中。 但除此之外,您將單元測試與集成測試混合在一起。
您需要使用@RunWith(MockitoJUnitRunner.class)注釋您的測試類,
或者
您需要使用@MockBean注釋您的模擬對象並將 @Autowired 添加到您的測試類 DataServiceImpl 對象中。
現在,讓我為你解釋一下。
單元測試
當您要編寫單元測試時,不應使用應用程序上下文(自動裝配)。
順便說一句,更好的方法是使用來自 Lombok 的 @RequiredArgsConstructor 注釋您的 DataServiceImpl 並從 CautionRepository 中刪除 @Autowired。 這將允許您在單元測試的設置方法中實例化 DataServiceImpl。
您的 DataServiceImpl 類應該是:
@Service
@RequiredArgsConstructor
public class DataServiceImpl implements DataService{
private final CautionRepository cautionRepository;
@Override
public void addCautions(List<CautionsDTO> cautions, Contrat contrat) {
// your code...
}
}
和你的新單元測試類:
@RunWith(MockitoJUnitRunner.class)
public class DataServiceImplTest{
private DataServiceImpl dataService;
@Mock
private CautionRepository cautionRepository;
@Before
public void setup() {
dataService = new DataServiceImpl(cautionsRepository);
}
@Test
public void addListCautionsTest() {
// your test code...
}
}
集成測試
現在,如果要創建集成測試,請使用@RunWith(SpringRunner.class) 。 通過這樣做,您的應用程序上下文將被加載。 在您的情況下,您可以通過使用@MockBean注釋您的對象在您的上下文中創建一個模擬 bean 。 這會將模擬對象注入您的上下文,並將在您的真實類中自動連接。
為此,您的新 DataServiceImpl 類可以保持與上述相同。 但是將您的集成測試更改為:
@RunWith(SpringRunner.class)
public class DataServiceImplTest{
@Autowired
private DataServiceImpl dataService;
@MockBean // it will be injected automatically
private CautionRepository cautionRepository;
@Test
public void addListCautionsTest() {
// your test code...
}
}
希望,你現在明白了你所做的區別和錯誤:)
您永遠不會向cautions
添加值,因此不會執行循環並且驗證必須失敗。
向列表中添加一個值,測試應該通過:
List<CautionsDTO> cautions = new ArrayList<>();
ContratExportation contrat = new ContratExportation();
CautionDTO caution = new CautionDTO();
cautions.add(caution);
dataDelService.addCautions(cautions,contrat);
這應該是執行測試的正確代碼
@RunWith(SpringRunner.class)
public class DataServiceImplTest{
@Autowired
private DataServiceImpl dataService;
@MockBean
private CautionRepository cautionRepository;
@Test
public void addListCautionsTest() {
List<CautionsDTO> cautions = new ArrayList<>();
ContratExportation contrat = new ContratExportation();
Caution caution = new Caution();
dataDelService.addCautions(cautions,contrat);
Mockito.verify(cautionRepository, times(1)).save(caution);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.