Mockito中常用的方法
when().thenReturn()
when(目標方法).thenReturn(調用目標方法後自定義的返回值)
Mockito.when(studentService.getStudentScore(Mockito.anyString())).thenReturn(.getStudentScoreInfo());
doReturn().when()
doReturn().when()
不會實際呼叫目標方法。when().thenReturn()
模擬呼叫外部API,假設找不到該API的子路徑,此方法可能會發生NullPointException,因為在when()
內實際呼叫了此方法。而doReturn().when()
則反之。小結:when().thenReturn()
會實際呼叫目標方法(成功)後返回自定義值;doReturn().when()
會自定義呼叫目標方法的返回值,但不會實際執行目標方法。
callRealMethod()
assertEquals("預計結果","實際結果")
assertEquals("85",actualAverageScore)
假設今天老師想要計算學生考試的平均成績,為此我們設計了一個 calculAverageScore 方法用於計算學生平均成績。我們可以透過 Unit Test 的方式來驗證此方法的業務邏輯是否正確,不需要實際去取得資料庫中學生的分數。
受測 Service 如下:
@Service("StudentService")
public class StudentService {
private StudentInformationRepository studentInformationRepository;
private StudentScoresRepository studentScoresRepository;
@Autowired
public StudentService(StudentInformationRepository studentInformationRepository,
StudentScoresRepository studentScoresRepository) {
this.studentInformationRepository = studentInformationRepository;
this.studentScoresRepository = studentScoresRepository;
}
public float calculAverageScore(List<StudentScores> studentScoreList){
int totalScore = studentScoreList.stream()
.mapToInt(studentScore -> Integer.parseInt(studentScore.getSsScore()))
.sum();
return (float) totalScore / studentScoreList.size();
}
Unit Test 如下:
@SpringBootTest
@ExtendWith(MockitoExtension.class)
class DemoApplicationTests {
@Spy
@InjectMocks
private StudentService studentService;
@BeforeEach
public void initMocks() {
MockitoAnnotations.openMocks(this);
}
@Test
public void calculAverageScoreTest(){
doReturn(getStudentScoresList()).when(studentService).getStudentScoresBySerialNumber(Mockito.anyString());
List<StudentScores> studentScoresList = studentService.getStudentScoresBySerialNumber("113A3G0006");
float actualAverageScore = studentService.calculAverageScore(studentScoresList);
float expectedAverage = (100 + 75 + 85) / studentScoresList.size();
// 進行 assert,檢查平均分數是否正確
assertEquals(expectedAverage, actualAverageScore, 1f); // 允許少量誤差
}
public List<StudentScores> getStudentScoresList(){
List<StudentScores> studentScoresList = new ArrayList<>();
studentScoresList.add(createStudentScore(115, "Math", "113-1", "100"));
studentScoresList.add(createStudentScore(115, "EnglishLanguage", "113-1", "75"));
studentScoresList.add(createStudentScore(115, "ChineseLanguage", "113-1", "85"));
return studentScoresList;
}
private StudentScores createStudentScore(int siId, String subject, String examId, String score) {
StudentScores studentScore = new StudentScores();
studentScore.setSsSiId(siId);
studentScore.setSsSubject(subject);
studentScore.setSsExamId(examId);
studentScore.setSsScore(score);
return studentScore;
}
}
此支單元測試方法為了驗證 StudentService 中的 calculAverageScore 方法,為了不讓程式實際執行資料庫查詢操作,我們透過 getStudentScoresList 方法模擬學生的成績資料。並藉由 doReturn 方法將 getStudentScoresList 方法內模擬的資料返回。
assertEquals 中的第三個參數表示的是”允許的誤差範圍”,這對於處理浮點數資料的判斷比較重要。