2016-12-15 151 views
1

这里使用Powermockito一个构造函数,给基类引用的是这种情况下,我有这样的事情在我的一类方法MyClass的嘲讽在Java

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

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

从本质上讲,您在代码中调用新的这一事实给您带来了悲伤 - 您创建了难以测试的代码。你可以看这些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 

所以你可以看到 - 没有在基地被调用;只是因为那个孩子的对象被“完全”嘲笑了。

整点是:您的在测代码只需要一个某一类型的对象;而且您事先知道这是孩子1还是孩子2。因此,您只需为该课程创建一个模拟;并使用PowerMockito按顺序返回模拟你刚刚创建的。

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

+0

感谢您的回复。是的,我们可以选择一些工厂模式,但我写的测试用例是针对遗留代码的,我们不想触摸现有的代码。除了更改现有代码之外,是否还有其他选择? – user2334926

+0

@ user2334926我更新了我的答案;拉了一个**为我工作的完整**例子。 – GhostCat