在 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 在测试中未被模拟。