模拟一个构造函数,它在java

时间:2016-12-15 17:07:46

标签: java unit-testing mockito powermockito

这是一个场景,我在一个类 MyClass

的方法中有类似的东西
public class MyClass{

    public Object build(Map map) {

        BaseClass cls;     

        if(SomeconditionTrue) {

         cls = new ChildClass1(new ABC());

        } else {

        cls = new ChildClass2(new ABC());

       }

       cls.callMethod();

    }

}

对于上面的场景,我正在使用PowerMockito编写测试用例,我想模拟这个方法调用cls.callMethod()。当我试图模拟时,它调用失败的实际方法callMethod()。有人可以帮我模仿那个方法吗?尝试使用PowerMockito PowerMockito.stub和一些其他选项使用几个场景,但它总是调用实际方法。模拟这个方法的原因是,它有一个不同的逻辑,它调用不同的API,方法相当复杂,因此我们需要模拟这个方法。

1 个答案:

答案 0 :(得分:1)

你可以转向Powermock,但这并不一定是解决此类问题的“最佳”答案。

从本质上讲,您在代码中调用 new 的事实让您感到悲伤 - 您创建了难以测试的代码。你可能会看到这些videos来理解我在说什么。

长话短说:而不是转向大型Powermock锤子,你可以改为修改你的代码;使用依赖注入。因此,不是自己创建这些对象,而是测试中的类可以使用一些工厂对象来提供它所需的对象。然后你可以使用任何“普通”的模拟框架,如EasyMock或Mockito来创建该工厂的模拟版本。

编辑:我认为你可能过度复杂了整个问题。你知道,有一个基类或两个子类并不重要。事情是:对于每种测试方法,您应该准确地了解将采用哪种路径。你要么想要创建一个child1,要么是一个孩子。因此,我为您创建了一个简化的解决方案:

package ghostcat.test;

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

class Abc {}

abstract class Base {
  void callMethod() {
    System.out.println("Base::callMethod");
  }
}

class ChildClass1 extends Base {
  ChildClass1(Abc abc) {}
}

class MyClass {
  public Object build() {
    System.out.println("build1");
    Base cls = new ChildClass1(new Abc());
    System.out.println("build2");
    cls.callMethod();
    System.out.println("build3");
    return null;
  } 
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MockNewTest {
  @Test
  public void test() throws Exception {
    ChildClass1 mock = Mockito.mock(ChildClass1.class);
PowerMockito.whenNew(ChildClass1.class).withArguments(Mockito.any(Abc.class)).thenReturn(mock);
    new MyClass().build();
}

}

打印:

build1
build2
build3

所以你可以看到 - 基地里没有任何东西被召唤;只是因为那个子对象被“完全”嘲笑了。

重点是:您的测试代码只需要某种类型的一个对象;而且你事先知道那是child1还是child2。所以你只需为该类创建一个 mock ;并使用PowerMockito返回你刚刚创建的模拟。

记录:我和间谍玩了一段时间;但他们在这里没有帮助;它们也不是必需的!