unit-testing
16
总安装量
11
周安装量
#20988
全站排名
安装命令
npx skills add https://github.com/leavesfly/jimi --skill unit-testing
Agent 安装分布
claude-code
9
opencode
7
trae
6
codex
6
antigravity
5
Skill 文档
åå æµè¯æè½å
ç¼åé«è´¨éåå æµè¯çä¸ä¸æåï¼åºäºJUnit 5åMockitoæ¡æ¶ã
æµè¯åå
- æµè¯ç¬ç«æ§ï¼æ¯ä¸ªæµè¯ç¨ä¾åºç¬ç«è¿è¡ï¼ä¸ä¾èµå ¶ä»æµè¯çæ§è¡é¡ºåºæç»æ
- åä¸èè´£ï¼æ¯ä¸ªæµè¯åªéªè¯ä¸ä¸ªå ·ä½çè¡ä¸ºæåºæ¯
- å½åæ¸
æ°ï¼æµè¯æ¹æ³ååºæ¸
æ¥æè¿°æµè¯åºæ¯ï¼æ¨èæ ¼å¼ï¼
æ¹æ³å_æµè¯åºæ¯_ææç»æ - è¦çå ¨é¢ï¼å æ¬æ£å¸¸åºæ¯ãè¾¹çæ¡ä»¶ãå¼å¸¸æ åµä¸ä¸ªç»´åº¦
æµè¯ç»æï¼AAA模å¼ï¼
æ¯ä¸ªæµè¯ç¨ä¾åºéµå¾ªArrange-Act-Assert䏿®µå¼ç»æï¼
@Test
void calculateTotal_withValidItems_returnsCorrectSum() {
// Arrange - å夿µè¯æ°æ®åä¾èµ
List<Item> items = Arrays.asList(
new Item("A", 10.0),
new Item("B", 20.0)
);
Calculator calculator = new Calculator();
// Act - æ§è¡è¢«æµè¯çæ¹æ³
double result = calculator.calculateTotal(items);
// Assert - éªè¯ç»ææ¯å¦ç¬¦åææ
assertEquals(30.0, result, 0.001);
}
å¸¸ç¨æè¨
JUnit 5æè¨
assertEquals(expected, actual)– éªè¯ç¸çæ§assertNotNull(actual)– éªè¯é空assertTrue(condition)/assertFalse(condition)– éªè¯å¸å°æ¡ä»¶assertThrows(Exception.class, () -> {...})– éªè¯å¼å¸¸æåºassertAll()– æ¹éæè¨ï¼å ¨é¨æ§è¡assertTimeout(duration, () -> {...})– éªè¯æ§è¡æ¶é´
AssertJæµå¼æè¨ï¼æ¨èï¼
assertThat(result)
.isNotNull()
.isInstanceOf(User.class)
.extracting(User::getName)
.isEqualTo("å¼ ä¸");
Mockä½¿ç¨æå
åºæ¬Mock
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUser_whenExists_returnsUser() {
// å®ä¹Mockè¡ä¸º
when(userRepository.findById(1L))
.thenReturn(Optional.of(new User("å¼ ä¸")));
// æ§è¡æµè¯
User user = userService.getUser(1L);
// éªè¯ç»æ
assertEquals("å¼ ä¸", user.getName());
// éªè¯æ¹æ³è°ç¨
verify(userRepository).findById(1L);
}
}
Mock注æäºé¡¹
- 使ç¨
@Mock注解æ è®°ä¾èµ - 使ç¨
@InjectMocksèªå¨æ³¨å ¥Mock对象 - 使ç¨
when().thenReturn()å®ä¹Mockè¿åå¼ - 使ç¨
verify()éªè¯æ¹æ³æ¯å¦è¢«è°ç¨ - 使ç¨
any()ãeq()çå¹é å¨çµæ´»å¹é åæ°
è¾¹çæ¡ä»¶æµè¯æ¸ å
å¿ é¡»æµè¯çè¾¹çæ¡ä»¶ï¼
- 空å¼ï¼nullï¼ï¼è¾å ¥åæ°ä¸ºnullçæ åµ
- 空éåï¼ç©ºå表ã空Mapã空å符串
- åå ç´ éåï¼åªæä¸ä¸ªå ç´ çéå
- 大鿰æ®ï¼å¤§æ°æ®éåºæ¯çæ§è½åæ£ç¡®æ§
- è¾¹çå¼ï¼æå¤§å¼ãæå°å¼ã0ã-1ç
- ç¹æ®å符ï¼ç©ºæ ¼ãæ¢è¡ç¬¦ãç¹æ®ç¬¦å·
- å¹¶ååºæ¯ï¼å¤çº¿ç¨å¹¶å访é®
æµè¯è¦ççç¥
æ¹æ³çº§è¦ç
æ¯ä¸ªpublicæ¹æ³è³å°å å«ä»¥ä¸æµè¯ï¼
- æ£å¸¸æ 嵿µè¯
- å¼å¸¸æ 嵿µè¯ï¼åæ°éæ³ãç¶æå¼å¸¸çï¼
- è¾¹çæ¡ä»¶æµè¯
忝è¦ç
- if/elseçæ¯ä¸ªåæ¯é½åºè¢«æµè¯è¦ç
- switch/caseçæ¯ä¸ªcaseé½åºæµè¯
- 循ç¯çè¾¹çæ¡ä»¶ï¼0次ã1次ã夿¬¡ï¼
æä½³å®è·µ
- æµè¯å è¡ï¼å¯è½çè¯éç¨TDDï¼æµè¯é©±å¨å¼åï¼
- å¿«éæ§è¡ï¼åå æµè¯åºè¯¥å¿«éæ§è¡ï¼é¿å ä¾èµå¤é¨èµæº
- å¯éå¤ï¼æµè¯ç»æåºè¯¥ç¨³å®å¯éå¤ï¼ä¸ä¾èµæ§è¡ç¯å¢
- èªå¨åï¼éæå°CI/CDæµç¨ä¸èªå¨æ§è¡
- 宿éæï¼æµè¯ä»£ç ä¹éè¦éæåç»´æ¤
忍¡å¼ï¼é¿å ï¼
â æµè¯ç§ææ¹æ³ï¼åºè¯¥æµè¯publicæ¥å£ï¼ â æµè¯ç¬¬ä¸æ¹åºï¼åºè¯¥Mockæï¼ â æµè¯getter/setterï¼æ²¡æå¿ è¦ï¼ â è¿åº¦Mockï¼å¯¼è´æµè¯èå¼±ï¼ â 忽ç¥å¼å¸¸æµè¯