【问题标题】:How can I suppress private method invocation in constructor?如何在构造函数中抑制私有方法调用?
【发布时间】:2014-07-03 18:03:35
【问题描述】:

我有一个非常简单的类,它有一个私有方法。问题是如何抑制这个方法调用?

这是我的代码:

public class Example { 
    private int value;

    public Example(int value) {
        this.value = value;
        method();
    }

    private void method() {
        throw new RuntimeException();
    }

    public int getValue() {
        return value;
    }
}

和测试代码(至少尝试):

public void test() throws Exception {

    PowerMockito.doNothing().when(Example.class, "method");
    final int EXPECTED_VALUE = 1;
    Example example = new Example(EXPECTED_VALUE);
    int RETRIEVED_VALUE = example.getValue();

    assertEquals(RETRIEVED_VALUE, EXPECTED_VALUE);
    verifyPrivate(Example.class, times(1)).invoke("method");
}

UPD

对我来说,遵守这两个条款很重要:

  1. PowerMockito.doNothing().when(Example.class, "method");
  2. PowerMockito.verifyPrivate(Example.class, times(1)).invoke("method");

【问题讨论】:

  • 你到底为什么要抛出一个新的异常?我不明白。
  • //method(); 应该可以解决问题
  • 这只是真实课堂的一个例子。
  • @Aaron 你可以做什么和不可以做什么?
  • 好的,我想他是在问如何模拟method,以便不调用它的实际实现。这是一个“我如何编写这个单元测试?”问题。

标签: java unit-testing mocking powermock


【解决方案1】:

由于您无法修改被测代码。我认为没有完美的解决方案。您需要部分模拟Example 实例。

List list = new LinkedList();
List spy = spy(list);
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);

但你不能这样做,因为你必须首先实例化你的对象。


所以我提出以下由两个测试组成的解决方法。第一个测试从类中删除私有method,实例化Example 并验证Example 是否正确初始化。 第二个测试实例化Example 并验证RuntimeException(私有method 副作用)。

import static org.junit.Assert.assertEquals;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.support.membermodification.MemberModifier.suppress;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Example.class)
public class ExampleTest {
    @Test
    public void constructor_should_initialize_the_v2alue() throws Exception {
        suppress(method(Example.class, "method"));

        final int EXPECTED_VALUE = 1;
        Example example = PowerMockito.spy(new Example(EXPECTED_VALUE));
        int RETRIEVED_VALUE = example.getValue();

        assertEquals(RETRIEVED_VALUE, EXPECTED_VALUE);
    }

    @Test(expected=RuntimeException.class)
    public void constructor_should_invoke_the_private_method() throws Exception {
        new Example(1);
    }
}

【讨论】:

  • 实际上我需要验证该方法是否也被调用(没有调用)。
  • 恕我直言,powermock/mockito 是不可能的。也许你可以用aspectj查看运行时编织/aop
猜你喜欢
  • 1970-01-01
  • 2020-07-24
  • 2017-08-17
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 2018-03-11
相关资源
最近更新 更多