Here's an example.
Account.java :
package com.jmock.vo;
public class Account {
private String id;
private String name;
private boolean activated;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isActivated() {
return activated;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
}
AccountServicesImpl.java is the class under test.
AccountServicesImpl.java :
package com.jmock.services.impl;
import org.springframework.beans.factory.annotation.Autowired;
import com.jmock.dao.AccountDAO;
import com.jmock.general.ErrorConst;
import com.jmock.services.exception.AccountServicesException;
import com.jmock.vo.Account;
public class AccountServicesImpl {
@Autowired
private AccountDAO accountDAO; //Spring injected
public Account getAccount(String id) throws AccountServicesException {
Account account = accountDAO.selectAccount(id);
if(account == null)
throw new AccountServicesException(ErrorConst.ERROR_ACCOUNT_UNKNOWN);
if(!account.isActivated())
throw new AccountServicesException(ErrorConst.ERROR_ACCOUNT_INACTIVE);
return account;
}
}
As you can see, there is 3 scenarios to implement :
- The normal test case
- The account unknown test case
- The account inactive test case
And here's the test class.
AccountServicesTest.java :
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.lang.reflect.Field;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Before;
import org.junit.Test;
import com.jmock.dao.AccountDAO;
import com.jmock.general.ErrorConst;
import com.jmock.services.exception.AccountServicesException;
import com.jmock.services.impl.AccountServicesImpl;
import com.jmock.vo.Account;
import org.junit.runner.RunWith;
@RunWith(JMock.class)
public class AccountServicesTest {
//Mock context
private Mockery context;
private AccountDAO accountDAO;
private AccountServicesImpl underTest;
@Before
public void before() throws Exception {
context = new JUnit4Mockery();
accountDAO = context.mock(AccountDAO.class);
underTest = new AccountServicesImpl();
//We use reflection to access the private field
Field fieldCurrencyServices = underTest.getClass().getDeclaredField("accountDAO");
fieldCurrencyServices.setAccessible(true);
fieldCurrencyServices.set(underTest, accountDAO);
}
@Test
public void testGetAccount() {
final Account account = new Account();
account.setId("124110002055");
account.setActivated(true);
context.checking(new Expectations() {{
oneOf (accountDAO).selectAccount(with(account.getId()));
will(returnValue(account));
}});
try {
underTest.getAccount(account.getId());
} catch (AccountServicesException ex) {
ex.printStackTrace();
fail("No exception expected");
}
}
@Test
public void testGetUnknownAccount() {
final Account account = new Account();
account.setId("124110002055");
account.setActivated(true);
context.checking(new Expectations() {{
oneOf (accountDAO).selectAccount(with(account.getId()));
will(returnValue(null));
}});
try {
underTest.getAccount(account.getId());
} catch (AccountServicesException ex) {
assertEquals(ErrorConst.ERROR_ACCOUNT_UNKNOWN, ex.getErrorId());
}
}
@Test
public void testGetInactiveAccount() {
final Account account = new Account();
account.setId("124110002055");
account.setActivated(false);
context.checking(new Expectations() {{
oneOf (accountDAO).selectAccount(with(account.getId()));
will(returnValue(account));
}});
try {
underTest.getAccount(account.getId());
} catch (AccountServicesException ex) {
assertEquals(ErrorConst.ERROR_ACCOUNT_INACTIVE, ex.getErrorId());
}
}
}
Here's are the dependencies you need to add to your pom.xml
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<version>2.5.1</version>
</dependency>
Just want to add a usefull link which is a link on the JMock documentation and more specifically on the cardinality part. Indeed you can use not only oneOf but atLeast(n).of, exactly(n), etc...
ReplyDeletehttp://www.jmock.org/cardinality.html
Don't forget the scope in the maven file :
ReplyDelete<scope>test</scope>
You can replace the reflection access by:
ReplyDeleteorg.apache.commons.beanutils.BeanUtils.setProperty(underTest, "accountDao", accountDao);
why reinvent the whell ?)
thanks for posting!
ReplyDeleteNice Example its very helpful
ReplyDelete