【问题标题】:Using another object as parameter in Jmockit Mocked object在 Jmockit 模拟对象中使用另一个对象作为参数
【发布时间】:2015-05-12 14:56:52
【问题描述】:

我是 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;
    }
}
}

(省略 Account 类,因为它应该是不言自明的。)

如果我将 mockLdapTemplate.search(query().base(anyString).where(anyString) .is("userA"), (AttributesMapper) any); 替换为 mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any),则测试通过(这是我所期望的,但这或多或少告诉我问题出在 LdapQuery 参数上)。

谢谢!

【问题讨论】:

    标签: java spring unit-testing junit jmockit


    【解决方案1】:

    你已经知道答案了:期望应该记为

    mockLdapTemplate.search((LdapQuery)withNotNull(), (AttributesMapper) any)
    

    因为这是从被测单元调用的唯一模拟方法。参数匹配器“any”、“withNotNull()”等只能用于调用 mocked 方法,而 LdapQuery 在测试中未被模拟。

    【讨论】:

    • 好的。所以我确实需要模拟 LdapQuery 吗?你能提供任何例子吗?当我传入“userA”参数时,我的测试在 is() 方法中。基本上没有它,测试并不能真正测试任何东西。
    • 你可以模拟LdapQuery,但这会变得复杂;一种可能的替代方法(取决于查询对象中合适的“getter”的可用性)是捕获传递给search 方法的查询对象,使用qry = withCapture() 作为参数匹配器(使用局部变量LdapQuery qry) .另一种选择是使用 Spring 的 org.springframework.ldap.test 工具编写集成测试。
    • 谢谢。我会尝试第一个。
    猜你喜欢
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多