在 Jmockit 模拟对象中使用另一个对象作为参数
Using another object as parameter in Jmockit Mocked object
我是 JMockit 的新手,并且已经成功地 运行 使用它进行了基本的单元测试。但是,我在尝试模拟 Spring LdapTemplate 时卡住了。问题似乎出在 LdapTemplate 使用的 LdapQuery 上。我也需要模拟这个吗?
JUnit 测试
@RunWith(JMockit.class)
public class MyTest {
@Mocked
LdapTemplate mockLdapTemplate;
@Test
public void retrieveAccount_test() {
Account acct = new Account();
acct.setEmail("foobar@gmail.com");
acct.setUserId("userA");
final List<Account> expected = Arrays.asList(acct);
new Expectations() {
{
mockLdapTemplate.search(query().base(anyString).where(anyString)
.is("userA"), (AttributesMapper) any);
result = expected;
}
};
AccountService service = new AccountServiceImpl(mockLdapTemplate);
Account account = service.retrieveAccount("userA");
assertThat(account, is(notNullValue()));
}
}
账户服务
public class AccountServiceImpl implements AccountService {
private LdapTemplate ldapTemplate;
@Autowired
public AccountServiceImpl(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
@Override
public Account retrieveAccount(String userId) {
LdapQuery query = query().base("ou=users").where("uid").is(userId);
List<Account> list = ldapTemplate.search(query,
new AccountMapper());
if (list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
public class AccountMapper implements
AttributesMapper<Account> {
@Override
public Account mapFromAttributes(Attributes attrs)
throws NamingException {
Account account = new Account();
account.setEmail((String) attrs.get("mail").get());
account.setUserId((String) attrs.get("uid").get());
return account;
}
}
}
(省略帐户 class,因为它应该不言自明。)
如果我用 mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any)
替换 mockLdapTemplate.search(query().base(anyString).where(anyString)
.is("userA"), (AttributesMapper) any);
测试通过(这是我所期望的,但这或多或少告诉我问题出在 LdapQuery 参数上)。
谢谢!
你已经知道答案了:期望值应该记为
mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any)
因为这是从被测单元调用的唯一模拟方法。参数匹配器 "any"、"withNotNull()" 等只能用于调用 mocked 方法,并且 LdapQuery
在测试中未被模拟。
我是 JMockit 的新手,并且已经成功地 运行 使用它进行了基本的单元测试。但是,我在尝试模拟 Spring LdapTemplate 时卡住了。问题似乎出在 LdapTemplate 使用的 LdapQuery 上。我也需要模拟这个吗?
JUnit 测试
@RunWith(JMockit.class)
public class MyTest {
@Mocked
LdapTemplate mockLdapTemplate;
@Test
public void retrieveAccount_test() {
Account acct = new Account();
acct.setEmail("foobar@gmail.com");
acct.setUserId("userA");
final List<Account> expected = Arrays.asList(acct);
new Expectations() {
{
mockLdapTemplate.search(query().base(anyString).where(anyString)
.is("userA"), (AttributesMapper) any);
result = expected;
}
};
AccountService service = new AccountServiceImpl(mockLdapTemplate);
Account account = service.retrieveAccount("userA");
assertThat(account, is(notNullValue()));
}
}
账户服务
public class AccountServiceImpl implements AccountService {
private LdapTemplate ldapTemplate;
@Autowired
public AccountServiceImpl(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
@Override
public Account retrieveAccount(String userId) {
LdapQuery query = query().base("ou=users").where("uid").is(userId);
List<Account> list = ldapTemplate.search(query,
new AccountMapper());
if (list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
public class AccountMapper implements
AttributesMapper<Account> {
@Override
public Account mapFromAttributes(Attributes attrs)
throws NamingException {
Account account = new Account();
account.setEmail((String) attrs.get("mail").get());
account.setUserId((String) attrs.get("uid").get());
return account;
}
}
}
(省略帐户 class,因为它应该不言自明。)
如果我用 mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any)
替换 mockLdapTemplate.search(query().base(anyString).where(anyString)
.is("userA"), (AttributesMapper) any);
测试通过(这是我所期望的,但这或多或少告诉我问题出在 LdapQuery 参数上)。
谢谢!
你已经知道答案了:期望值应该记为
mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any)
因为这是从被测单元调用的唯一模拟方法。参数匹配器 "any"、"withNotNull()" 等只能用于调用 mocked 方法,并且 LdapQuery
在测试中未被模拟。