锘??xml version="1.0" encoding="utf-8" standalone="yes"?>精品久久久久久久中文字幕,你懂的亚洲视频,狠狠综合久久av一区二区蜜桃http://www.aygfsteel.com/koradji/category/47735.htmlzh-cnMon, 31 Jan 2011 22:55:51 GMTMon, 31 Jan 2011 22:55:51 GMT60銆愯漿甯栥慾Mock Argument Interceptor - 涓縐嶇嫭鐗圭殑璁捐鎬濊礬http://www.aygfsteel.com/koradji/articles/343822.htmlkoradjikoradjiMon, 31 Jan 2011 14:24:00 GMThttp://www.aygfsteel.com/koradji/articles/343822.htmlhttp://www.aygfsteel.com/koradji/comments/343822.htmlhttp://www.aygfsteel.com/koradji/articles/343822.html#Feedback0http://www.aygfsteel.com/koradji/comments/commentRss/343822.htmlhttp://www.aygfsteel.com/koradji/services/trackbacks/343822.html Motivation
An Object you need to test is constructing another complex object internally which you cannot access and this object is passed to a collaborator you can replace with a mock.
Solution
Write an Interceptor (a custom jMock Stub ) to intercept the argument passed to the mocked method. The Interceptor exposes the argument, allowing for standard jUnit assertions.
Alternatives

    * Use a custom jMock Constraint when the argument's asserted state is simple.
    * Use a Fake Object when a class cannot be dynamically mocked.

Example

public void testInterceptArgument() {

    List arguments = new ArrayList();

    Mock mockSubmissionTracker = mock(SubmissionTracker.class);
    mockSubmissionTracker.expects(once()).method("record").will(captureArgumentsIn(arguments));

    SecretLottery lotto = new SecretLottery( (SubmissionTracker)mockSubmissionTracker.proxy());

    lotto.createTicket();

    LotteryTicket ticket = (LotteryTicket) arguments.get(0);
    assertEquals("Secret Number", 12345, ticket.number);
}

private Stub captureArgumentsIn(List argumentList) {

    return new ArgumentInterceptor(argumentList);

}

class ArgumentInterceptor implements Stub {

    List arguments;

    public ArgumentInterceptor(List argumentList) {
        arguments = argumentList;
    }

    public Object invoke(Invocation invocation) throws Throwable {
        arguments.addAll(invocation.parameterValues);
        return null;
    }

    public StringBuffer describeTo(StringBuffer buffer) {
        return buffer;
    }
}

The Traditional jMock approach
The traditional way to handle this with jMock is to create a custom Constraint to verify the argument passed into the mocked method. Unfortunatly, this technique can produce a less explict test and a lot of supporting code. The above example handled with a traditional jMock Constraint would look like the following...

public void testInterceptArgument() {

    Mock mockSubmissionTracker = mock(SubmissionTracker.class);
    mockSubmissionTracker.expects(once()).method("record").with(ticketNumber(12345));

    SecretLottery lotto = new SecretLottery( (SubmissionTracker) mockSubmissionTracker.proxy());

    lotto.createTicket();
}

private Constraint ticketNumber(final int ticketNumber) {

    return new Constraint() {

        public boolean eval(Object arg) {

            LotteryTicket ticket = (LotteryTicket) arg;  
            return ticketNumber == ticket.number;
        }

        public StringBuffer describeTo(StringBuffer buffer) {
            return buffer.append(ticketNumber);
        }
    }
}

While this example works fairly well, each new test method would likely require its own Constraint. When the verification in the eval method becomes complex, it can become difficult to determine why a test is failing. An Argument Interceptor allows for traditional jUnit assertions, providing clearer failures for complex verfications.


koradji 2011-01-31 22:24 鍙戣〃璇勮
]]>
主站蜘蛛池模板: 广安市| 积石山| 松滋市| 镇雄县| 商丘市| 临夏市| 日照市| 忻城县| 阿坝县| 大宁县| 潞城市| 密山市| 龙游县| 鲁山县| 锡林郭勒盟| 波密县| 武穴市| 泰安市| 河津市| 南江县| 仙桃市| 浮山县| 岑巩县| 嘉鱼县| 伊宁县| 南雄市| 杂多县| 宿州市| 岳池县| 抚宁县| 诏安县| 恩施市| 南江县| 额敏县| 承德县| 鹿泉市| 墨玉县| 乌审旗| 岢岚县| 景宁| 迁安市|