JMock实践---(一)定义Expectations

来源:互联网 发布:jessyline姐妹品牌js 编辑:程序博客网 时间:2024/06/05 06:01

声明:

Author:赵志乾

Date:2017-7-30

Declaration:All Right Reserved!!!


1、自动创建Mock对象

    如果我们定义一个字段来引用Mock对象,那么JMock便会自动地完成对象的实例化,从而减少一些样板式的代码书写,减轻开发人员的负担。当然,为了让JMock知道要实例化那个字段所引用的对象,需要使用@Mock进行注解。如下面实例所示:

@Mock MyClass objMock;

2、指定Expectations

    Expectations在Mockery对象中进行定义(假设先前已经创建了Mockery对象并命名为context),并且其内容要求放在双重花括号内。如下所示:

public void testSomeAction() {    ... set up ...        context.checking(new Expectations() {{        ... expectations go here ...    }});        ... code being tested ...        ... assertions ...}

    Expectations块可以包含任意数量的预期,每一个预期都有如下结构。

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));

    最常用到的结构如下:

    调用次数(Mock对象名).要调用的方法名(参数);will(被调后要执行的动作);

    其中,除了调用次数和Mock对象名外,其他各子句都是可选的。下面的测试方法给出了示例:

@Test public void returnsCachedObjectWithinTimeout() {    context.checking(new Expectations() {{        oneOf (clock).time(); will(returnValue(loadTime));        oneOf (clock).time(); will(returnValue(fetchTime));                    allowing (reloadPolicy).shouldReload(loadTime, fetchTime); will(returnValue(false));                oneOf (loader).load(KEY); will(returnValue(VALUE));    }});            Object actualValueFromFirstLookup = cache.lookup(KEY);    Object actualValueFromSecondLookup = cache.lookup(KEY);            assertSame("should be loaded object", VALUE, actualValueFromFirstLookup);    assertSame("should be cached object", VALUE, actualValueFromSecondLookup);}

     一个测试方法中可以包含多个Expectations块,后面的Expectations块会追加到其前面的那个Expectations块之后,这在呈现形式上对Expectations进行了清晰的分类。比如上面的那个测试可以写成下面的样式。

@Test public void returnsCachedObjectWithinTimeout() {    context.checking(new Expectations() {{        oneOf (clock).time(); will(returnValue(loadTime));        oneOf (loader).load(KEY); will(returnValue(VALUE));    }});    Object actualValueFromFirstLookup = cache.lookup(KEY);    context.checking(new Expectations() {{        oneOf (clock).time(); will(returnValue(fetchTime));                    allowing (reloadPolicy).shouldReload(loadTime, fetchTime); will(returnValue(false));    }});        Object actualValueFromSecondLookup = cache.lookup(KEY);            assertSame("should be loaded object", VALUE, actualValueFromFirstLookup);    assertSame("should be cached object", VALUE, actualValueFromSecondLookup);}

    Expectations块也可以用函数进行封装,从而使简化测试方法代码的复杂度,如下例所示:

@Test public void returnsCachedObjectWithinTimeout() {    initiallyLoads(VALUE);    Object valueFromFirstLookup = cache.lookup(KEY);    cacheHasNotExpired();        Object valueFromSecondLookup = cache.lookup(KEY);        assertSame("should have returned cached object",                valueFromFirstLookup, valueFromSecondLookup);}private void initiallyLoads(Object value) {    context.checking(new Expectations() {{        oneOf (clock).time(); will(returnValue(loadTime));        oneOf (loader).load(KEY); will(returnValue(value));    }});}private void cacheHasNotExpired() {    context.checking(new Expectations() {{        oneOf (clock).time(); will(returnValue(fetchTime));                    allowing (reloadPolicy).shouldReload(loadTime, fetchTime); will(returnValue(false));    }});}


注:本博客中的实例代码均来自于JMock Cookbook。




原创粉丝点击