标签存档: jmock

jmock2学习笔记-续

总结下这几天初步学习mock的心得. 文中大部分内容来自官网文档.

创建Mock对象

Mockery context = new Mockery();
Turtle turtle = context.mock(Turtle.class);
Turtle turtle2 = context.mock(Turtle.class, "turtle2");

创建Mock Expections

... create mock objects ...
public void testSomeAction() {
    ... set up ...
    context.checking(new Expectations() {{
        ... <expections block> ...
    }});
   ... call code being tested ...
}

expections 这里指的是jmock在不同情况下的预期值。expections 是jmcok的最重要部分之一。可以模拟用户在不同情况下返回不同的结果。

<expections block>这里是可以设置多个expections 。

Expectations

expections的结构如下:

invocation-count (mock-object).method(argument-constraints);
    inSequence(sequence-name);
    when(state-machine.is(state-name));
    will(action);
    then(state-machine.is(new-state-name));

上面是一个通用的结构。所有expecions都采用相同或更简洁的结构。

invocation-count mock调用频率。oneOf表示调用一次后这个expections即失效。
mock-object mock对象。即上面Mockery创建的对象。
method 用mock代替实现接口的一个方法。所以mock必须使用接口编程。
argument-constraints mock参数条件。即mock指定方法的参数。
when … will…then … 类似于if .. else… 这样的语句。简单的条件表达式
action mock符合条件后,执行操作。一般是返回结果。或者抛出异常
state-machine 条件表达式。

下面详细讲解下expectations各个部分。

Invocation Count

oneOf 只执行一次
exactly(n).of 执行指定n次
atLeast(n).of 至少执行n次
atMost(n).of 最多执行n次
between(min,max).of 可以执行min-max次
allowing 允许执行,不受限制
ignoring 功能同allowing类似。这里主要字面上区分allowing
never 不允许执行

Actions

will(returnValue(v)) 返回一个值。Object类型任意。集合类型不建议这里返回。虽然也可以
will(returnIterator(c)) 返回一个集合类型的值。
will(returnIterator(v1, v2, …, vn)) 返回一个集合类型的值。可以用多个,来分隔。
will(throwException(e)) 抛出一个异常。
will(doAll(a1, a2, …, an)) 嵌套执行多个actoin。不常用。

Sequences

设定mock方法调用的顺序。简单的看下面代码片段。
定义了先save后countUser。调用的时候也必须找这个顺序。否则用例失败。

        public void testCountUserSequences() {
                final Sequence testSequence = mockery.sequence("testSequence");

                final User _user = genUser();

                mockery.checking(new Expectations() {
                        {
                                oneOf(userDao).save(_user);
                                inSequence(testSequence);
                                will(returnValue(_user));

                                oneOf(userDao).countUser();
                                inSequence(testSequence);
                                will(returnValue(1));
                        }
                });

                assertEquals(userService.save(_user).getUsername(), "fengsage");
                assertEquals(userService.countUser(), 1);
        }

jmock2学习笔记

目前晚上学习jmock。

Issue: spring+annotations使用jmock

遇到了这个场景。stackoverflow上有人问过这个问题,这里贴一下。

http://stackoverflow.com/questions/1638911/mock-object-and-spring-annotations

关键是使用ReflectionTestUtils的方法。这个方法在spring-test工程的相关jar包。

    ...
    @Autowired
    private UserService	userService;
    private UserDao	userDao	= null;
    ...
    ReflectionTestUtils.setField(userService, "userDao", userDao, UserDao.class);
    ...

Issue:入参对象时。mock表达式传入对象必须和实际传入对象为同一句柄。

       
    final User _user = genUser();

    mockery.checking(new Expectations() {
        {
            one(userDao).queryUser(_user);
            List<User> userList = new ArrayList<User>();
            userList.add(genUser());
            userList.add(genUser());
            will(returnValue(userList));
        }
    });

    List<User> users = userService.queryUser(_user);

共用一个_user句柄。否则报错。

Issues:jmock一个异常错误

will(throwException(new RuntimeException("test exception")));

推荐链接:http://superleo.iteye.com/blog/143493

相关:jmock2学习笔记-续