Java 如何使用PowerMockito模拟私有字段?

Java 如何使用PowerMockito模拟私有字段?,java,junit,powermock,powermockito,Java,Junit,Powermock,Powermockito,作为副本提出的解决方案不是PowerMockito解决方案,因此无法回答此问题。此外,下面合理地回答了这个问题。 IDK,如果这是一个重复或没有,但我肯定找不到有问题的项目,如果它是。我一直希望这是非常简单的,因为反射非常简单,但我更愿意使用正确的工具 澄清:遗留代码。没有能手/二传手 对此使用Whitebox是否正确?我认为这是“禁区”,即内部API的一部分。。。或者这是严格的Mockito?参见Whitebox.setInternalState(…) 例如-需要测试的给定类A: public

作为副本提出的解决方案不是PowerMockito解决方案,因此无法回答此问题。此外,下面合理地回答了这个问题。

IDK,如果这是一个重复或没有,但我肯定找不到有问题的项目,如果它是。我一直希望这是非常简单的,因为反射非常简单,但我更愿意使用正确的工具

澄清:遗留代码。没有能手/二传手


对此使用Whitebox是否正确?我认为这是“禁区”,即内部API的一部分。。。或者这是严格的Mockito?

参见
Whitebox.setInternalState(…)

例如-需要测试的给定类
A

public class A {
    private B b;

    public A() {
        b = new B();
    }

    public void doSomething() {
        b.doSomething();
    }

}
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.Whitebox;

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    @Mock
    private B b;

    private A a;

    @Before
    public void prepareTest() {
        doNothing().when(b).doSomething();

        a = new A();
        Whitebox.setInternalState(a, B.class, b);
    }

    @Test
    public void doSomething() {
        a.doSomething();
        verify(b).doSomething();
    }

}
它有一个
B
的私有实例:

public class B {

    public void doSomething() {
        // some long running, resource intensive process...
        System.out.println("Real B.doSomething() was invoked.");
    }

}
然后可以使用
Whitebox
设置
A
的私有状态,以便对其进行测试:

public class A {
    private B b;

    public A() {
        b = new B();
    }

    public void doSomething() {
        b.doSomething();
    }

}
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.Whitebox;

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    @Mock
    private B b;

    private A a;

    @Before
    public void prepareTest() {
        doNothing().when(b).doSomething();

        a = new A();
        Whitebox.setInternalState(a, B.class, b);
    }

    @Test
    public void doSomething() {
        a.doSomething();
        verify(b).doSomething();
    }

}

请参见
Whitebox.setInternalState(…)

例如-需要测试的给定类
A

public class A {
    private B b;

    public A() {
        b = new B();
    }

    public void doSomething() {
        b.doSomething();
    }

}
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.Whitebox;

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    @Mock
    private B b;

    private A a;

    @Before
    public void prepareTest() {
        doNothing().when(b).doSomething();

        a = new A();
        Whitebox.setInternalState(a, B.class, b);
    }

    @Test
    public void doSomething() {
        a.doSomething();
        verify(b).doSomething();
    }

}
它有一个
B
的私有实例:

public class B {

    public void doSomething() {
        // some long running, resource intensive process...
        System.out.println("Real B.doSomething() was invoked.");
    }

}
然后可以使用
Whitebox
设置
A
的私有状态,以便对其进行测试:

public class A {
    private B b;

    public A() {
        b = new B();
    }

    public void doSomething() {
        b.doSomething();
    }

}
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.Whitebox;

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    @Mock
    private B b;

    private A a;

    @Before
    public void prepareTest() {
        doNothing().when(b).doSomething();

        a = new A();
        Whitebox.setInternalState(a, B.class, b);
    }

    @Test
    public void doSomething() {
        a.doSomething();
        verify(b).doSomething();
    }

}

私有代码不应该被模仿。必须模拟私有依赖关系是一种代码气味。代码可能需要重构,不管是不是遗留的。这并不意味着你可以选择。不是我不能。他们不会为此付出代价,如果我这样做而不是我应该做的,坏事就会发生在我身上。这也不是说我不能只做一次,但如果我开始这样做作为一项政策,我将不得不重写整个应用程序。所以我的政策是,我可以把马引向水边,但我不能让管理层为良好的编码实践买单。请参阅
Whitebox.setInternalState(…)
。确保人们理解预算会导致技术债务。这一点经常被提及,以至于现在谈论它是一种禁忌。让白盒作为答案,我会选择。私人代码不应该被嘲笑。必须模拟私有依赖关系是一种代码气味。代码可能需要重构,不管是不是遗留的。这并不意味着你可以选择。不是我不能。他们不会为此付出代价,如果我这样做而不是我应该做的,坏事就会发生在我身上。这也不是说我不能只做一次,但如果我开始这样做作为一项政策,我将不得不重写整个应用程序。所以我的政策是,我可以把马引向水边,但我不能让管理层为良好的编码实践买单。请参阅
Whitebox.setInternalState(…)
。确保大家都知道预算会导致技术债务。这一点已经被提得太多了,现在谈论它已经成了禁忌。让白盒作为答案,我会选择。