का उपयोग कर स्प्रिंग सर्विस यूनिट परीक्षण अब तक एसओ से जवाब मेरी समस्याओं के लिए पूरी तरह से संतोषजनक रहा है। मैं जूनिट और मॉकिटो के साथ यूनिट परीक्षण सीख रहा हूं और मैं अपनी सेवा कक्षा का परीक्षण करना चाहता हूं जो कि मेरे स्प्रिंग वेब ऐप का हिस्सा है। मैंने कई ट्यूटोरियल और लेख पढ़े और मुझे अभी भी मेरी सेवा परत के लिए उचित यूनिट परीक्षण लिखने में समस्याएं हैं। मैं अपने सवालों के जवाब जानना चाहते हैं, लेकिन पहले मैं कुछ कोड पेस्ट करें:मॉकिटो
सेवा वर्ग
public class AccountServiceImpl implements AccountService {
@Autowired
AccountDao accountDao, RoleDao roleDao, PasswordEncoder passwordEncoder, SaltSource saltSource;
@PersistenceContext
EntityManager entityManager;
public Boolean registerNewAccount(Account newAccount) {
entityManager.persist(newAccount);
newAccount.setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
setRoleToAccount("ROLE_REGISTERED", newAccount);
return checkIfUsernameExists(newAccount.getUsername());
}
public void setRoleToAccount(String roleName, Account account) {
List<Role> roles = new ArrayList<Role>();
try {
roles.add(roleDao.findRole(roleName));
} catch(RoleNotFoundException rnf) {
logger.error(rnf.getMessage());
}
account.setRoles(roles);
}
public Boolean checkIfUsernameExists(String username) {
try {
loadUserByUsername(username);
} catch(UsernameNotFoundException unf) {
return false;
}
return true;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
Account loadedAccount = accountDao.findUsername(username);
return loadedAccount;
} catch (UserNotFoundException e) {
throw new UsernameNotFoundException("User: " + username + "not found!");
}
}
}
मेरे अधूरा परीक्षण वर्ग
@RunWith(MockitoJUnitRunner.class)
public class AccountServiceImplTest {
private AccountServiceImpl accountServiceImpl;
@Mock private Account newAccount;
@Mock private PasswordEncoder passwordEncoder;
@Mock private SaltSource saltSource;
@Mock private EntityManager entityManager;
@Mock private AccountDao accountDao;
@Mock private RoleDao roleDao;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
accountServiceImpl = new AccountServiceImpl();
ReflectionTestUtils.setField(accountServiceImpl, "entityManager", entityManager);
ReflectionTestUtils.setField(accountServiceImpl, "passwordEncoder", passwordEncoder);
ReflectionTestUtils.setField(accountServiceImpl, "saltSource", saltSource);
ReflectionTestUtils.setField(accountServiceImpl, "accountDao", accountDao);
ReflectionTestUtils.setField(accountServiceImpl, "roleDao", roleDao);
}
@Test
public void testRegisterNewAccount() {
Boolean isAccountCreatedSuccessfully = accountServiceImpl.registerNewAccount(newAccount);
verify(entityManager).persist(newAccount);
verify(newAccount).setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
assertTrue(isAccountCreatedSuccessfully);
}
@Test
public void testShouldSetRoleToAccount() throws RoleNotFoundException{
Role role = new Role(); //Maybe I can use mock here?
role.setName("ROLE_REGISTERED");
when(roleDao.findRole("ROLE_REGISTERED")).thenReturn(role);
accountServiceImpl.setRoleToAccount("ROLE_REGISTERED", newAccount);
assertTrue(newAccount.getRoles().contains(role));
}
}
प्रश्न :
- यूनिट परीक्षण करने का सबसे अच्छा तरीका क्या है जहां मेरी सेवा कक्षा में विधियों में विधियां हैं? क्या मैं उन्हें ऊपर की तरह अलग से परीक्षण कर सकता हूं? [मैंने क्लीनर कोड रखने के लिए अपने कोड को कुछ तरीकों से विभाजित किया]
- क्या testRegisterNewAccount() मेरी सेवा विधि के लिए अच्छा यूनिट परीक्षण है? टेस्ट हरा है हालांकि मुझे इसके बारे में निश्चित नहीं है।
- मुझे अपने testShouldSetRoleToAccount में विफलता मिल रही है। मैं क्या गलत कर रहा हूं?
- checkIfUsernameExists का परीक्षण कैसे करें?
हो सकता है कि किसी ने मुझे इस के साथ मदद मिलेगी, क्योंकि मैं कुछ दिनों के खर्च और मैं एक प्रगति :(
अद्यतन नहीं किया
समाप्त परीक्षण वर्ग
@RunWith(MockitoJUnitRunner.class)
public class AccountServiceImplTest extends BaseTest {
private AccountServiceImpl accountServiceImpl;
private Role role;
private Account account;
@Mock private Account newAccount;
@Mock private PasswordEncoder passwordEncoder;
@Mock private SaltSource saltSource;
@Mock private EntityManager entityManager;
@Mock private AccountDao accountDao;
@Mock private RoleDao roleDao;
@Before
public void init() {
accountServiceImpl = new AccountServiceImpl();
role = new Role();
account = new Account();
ReflectionTestUtils.setField(accountServiceImpl, "entityManager", entityManager);
ReflectionTestUtils.setField(accountServiceImpl, "passwordEncoder", passwordEncoder);
ReflectionTestUtils.setField(accountServiceImpl, "saltSource", saltSource);
ReflectionTestUtils.setField(accountServiceImpl, "accountDao", accountDao);
ReflectionTestUtils.setField(accountServiceImpl, "roleDao", roleDao);
}
@Test
public void testShouldRegisterNewAccount() {
Boolean isAccountCreatedSuccessfully = accountServiceImpl.registerNewAccount(newAccount);
verify(entityManager).persist(newAccount);
verify(newAccount).setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
assertTrue(isAccountCreatedSuccessfully);
}
@Test(expected = IllegalArgumentException.class)
public void testShouldNotRegisterNewAccount() {
doThrow(new IllegalArgumentException()).when(entityManager).persist(account);
accountServiceImpl.registerNewAccount(account);
}
@Test
public void testShouldSetRoleToAccount() throws RoleNotFoundException {
when(roleDao.findRole(anyString())).thenReturn(role);
accountServiceImpl.setRoleToAccount("ROLE_REGISTERED", account);
assertTrue(account.getRoles().contains(role));
}
@Test
public void testShouldNotSetRoleToAccount() throws RoleNotFoundException {
when(roleDao.findRole(anyString())).thenThrow(new RoleNotFoundException());
accountServiceImpl.setRoleToAccount("ROLE_RANDOM", account);
assertFalse(account.getRoles().contains(role));
}
@Test
public void testCheckIfUsernameExistsIsTrue() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenReturn(account);
Boolean userExists = accountServiceImpl.checkIfUsernameExists(anyString());
assertTrue(userExists);
}
@Test
public void testCheckIfUsernameExistsIsFalse() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenThrow(new UserNotFoundException());
Boolean userExists = accountServiceImpl.checkIfUsernameExists(anyString());
assertFalse(userExists);
}
@Test
public void testShouldLoadUserByUsername() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenReturn(account);
Account foundAccount = (Account) accountServiceImpl.loadUserByUsername(anyString());
assertEquals(account, foundAccount);
}
@Test(expected = UsernameNotFoundException.class)
public void testShouldNotLoadUserByUsername() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenThrow(new UsernameNotFoundException(null));
accountServiceImpl.loadUserByUsername(anyString());
}
}
धन्यवाद डेविड। प्रश्न 1 का उत्तर दें मैं पूरी तरह से समझता हूं और मैंने विकल्प 1 चुना है। प्रश्न 3 के बारे में मैंने एक समस्या हल करने में कामयाब रहे। मुझे नए ऑपरेटर द्वारा बनाए गए खाते के साथ नकली खाता बदलना पड़ा और यह था [एसआईसी!] :)। प्रश्न 4 ने भी मेरी मदद की, लेकिन मुझे अन्य समस्याएं हैं। जैसा कि आप अपने संकेतों के लिए धन्यवाद देख सकते हैं, मैंने अपने सभी तरीकों के लिए परीक्षण लिखने में कामयाब रहे। वे testShouldNotSetRoleToAccount और testShouldNotLoadUserByUsername को छोड़कर ठीक काम करते हैं। जब "अपेक्षित = ..." होता है तो दोनों विफल हो जाते हैं। इसके बिना ठीक है। इसके अलावा पहले भी त्रुटि बनाता है और परीक्षण त्रुटि है। क्या तुम मेरी मदद कर सकते हो? –
क्षमा करें मुझे वापस आने के लिए मुझे थोड़ी देर लग गई है। यदि वे परीक्षण अपेक्षित अपवाद सेट के साथ विफल हो जाते हैं, तो इसका मतलब है कि अपवाद वास्तव में फेंक नहीं रहा है। क्या आप वाकई 'रोलडाओ' और 'अकाउंटडाओ' को वास्तव में मोक्स पर सेट कर चुके हैं? आप इसे डीबगर के साथ देख सकते हैं। साथ ही, आप 'anyString()' का सही ढंग से उपयोग नहीं कर रहे हैं - यह वास्तव में आपकी विधि को चलाने के लिए, स्टबिंग और सत्यापन के लिए है; मुझे नहीं पता कि यह आपकी समस्या का कारण है या नहीं। उन लाइनों में जहां आप वास्तव में अपनी विधियों को चलाते हैं, वास्तविक मूल्य डाल दें जिसे आप पास करना चाहते हैं, 'anyString() 'के बजाय। –
एह लॉल, मैं बेवकूफ हूँ। यह त्रुटि जो मैं इसके बारे में बात कर रहा था वह केवल लॉगर से कंसोल जानकारी थी। भूमिका में जब अपवाद पकड़ा जाता है तो वहां लॉगजर होता है। आतंक (..): पी। मैंने अपने टेस्ट कोड को अच्छी तरह से देखा और अब सबकुछ ठीक है। testShouldNotSetRoleToAccount और testCheckIfUsernameExistsIsFalse में "अपेक्षित" की आवश्यकता नहीं है। बाद में मैं अपनी टेस्ट क्लास अपडेट करूंगा और हम इस चर्चा को बंद कर सकते हैं। एक बार डेविड धन्यवाद, आपके संकेत बहुत उपयोगी थे :) –