PowerMockito whenNew thenReturn 不适用于传递类

问题描述

我有以下场景

Class A {
  someMethod() {
    B b = new B();
    b.someMethod();
  }
}

Class B {
  String someMethod() {
    C c = new C();
    return c.someMethod();
  }
}

Class C {
  String someMethod() {
    D d = new D();
    return d.getId()
  }
}

Class D {
  getId() {
    return "id123";
  }
}

我在 UT 做什么

@RunWith(powermockrunner.class)
@PrepareForTest({A.class,B.class,C.class})
MyTest {
  public void basictest() {
    D mockDClass = mock(D.class);
    when(mockDClass.getId()).thenReturn("mockedId");
    powermockito.whenNew(D.class).withAnyArguments().thenReturn(mockClass);
  }
}

在我的测试中,它应该返回 mockedId 但控制权转到实际方法

知道我做错了什么吗? 当我在我测试的课程中做 new 时,whenNew 是否有效?而不是针对我描述的情况。

----------------------更新-------------------- 写了一个简单的模块来测试上面的

public class A {
  public String someMethod() {
    B b = new B();
    return b.someMethod();
  }
}

public class B {
  public String someMethod() {
    C c = new C();
    return c.someMethod();
  }
}

public class C {
  public String someMethod() {
    D d = new D();
    return d.getId();
  }
}

public class D {
  public String getId() {
    return "id123";
  }
}

测试:

import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.powermockrunner;

import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;

@RunWith(powermockrunner.class)
@PrepareForTest({A.class,C.class})
public class ATest extends TestCase {
  @Test
  public void mocktest() {
    D mockD = mock(D.class);
    when(mockD.getId()).thenReturn("this is from mock");
    powermockito.whenNew(D.class).withAnyArguments().thenReturn(mockD);
    A a = new A();
    System.out.println(a.someMethod());
  }
}

这个测试的输出是这样的:

enter image description here

这个小测试有效,所以我在实际测试中做错了。

解决方法

whenNew 应该在每次你模拟的对象被实例化时工作。您实际上应该将行 'when(D.getId()).thenReturn("mockedId")' 替换为 'when(mockDClass.getId).thenReturn("mockedId")'。 以下代码片段应该有效:

C 测试:

@RunWith(PowerMockRunner.class)
@PrepareForTest({C.class})
public class CTest {

  @Test
  public void someMethodTest() throws Exception {
    D mockDClass = mock(D.class);
    when(mockDClass.getId()).thenReturn("mockedId");
    PowerMockito.whenNew(D.class).withAnyArguments().thenReturn(mockDClass);
    C c = new C();

    String response = c.someMethod();
    verifyNew(D.class).withNoArguments();
    assertEquals("mockedId",response);
  }
}

D 测试:

@RunWith(PowerMockRunner.class)
public class DTest {

  @Test
  public void testId() throws Exception {
    D mockDClass = mock(D.class);
    when(mockDClass.getId()).thenReturn("mockedId");
    PowerMockito.whenNew(D.class).withAnyArguments().thenReturn(mockDClass);
    D d = new D();

    verifyNew(D.class).withNoArguments();
    String response = d.getId();
    assertEquals("mockedId",response);
  }
}