模拟使用Java中Powermockito提供基类引用的构造函数 [英] Mocking of a constructor which gives the base class reference using Powermockito in java

查看:215
本文介绍了模拟使用Java中Powermockito提供基类引用的构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,我的类之一 MyClass

Here is the scenario, I have something like this in one of my method of a class 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进行调用,因此该方法非常复杂,因此我们需要模拟此方法。

For the above scenario, I am writing a test case using PowerMockito, I want to mock this method call, cls.callMethod(). When i am trying to mock, it calls the actual Method callMethod() which is failing. can some body please help me to mock that method call? Tried using couple of scenarios using PowerMockito PowerMockito.stub and some of other options, but its always calling the actual method. The reason to mock this method is, it has a different logic all together and it makes calls to different APIs, the method is quite complex, hence we need to mock this method.

推荐答案

您可以为此使用Powermock,但这不一定是解决此类问题的最佳答案。

You can turn to Powermock for this, but that is not necessarily the "best" answer to such problems.

在本质上,您在代码中调用 new 的事实使您感到悲伤-您由此创建了难以测试的代码。您可能会看这些视频,以了解我在说什么。

In essence, the fact that you are calling new in your code gives you grief - you created hard-to-test code by that. You might watch these videos to understand what I am talking about.

长话短说:您不必重做Powermock锤子,而可以重新编写代码;使用依赖注入。因此,被测试的类可以使用一些工厂对象来提供所需的对象,而不是自己创建这些对象。然后,您可以使用任何普通的模拟框架,例如EasyMock或Mockito来创建该工厂的模拟版本。

Long story short: instead of turning to the big Powermock hammer you could instead rework your code; to use dependency injection. So instead of creating these objects itself, your class under test could use some factory object to provide that object it needs. And then you can use any "ordinary" mocking framework such as EasyMock or Mockito to create a mocked version of that factory.

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

I think you might have over-complicated the whole issue. You see, it doesn't really matter that there is a base class, or two child classes. Thing is: for each of your test methods you should exactly understand which path will be taken. You either want that a child1 is created, or a child. Thus I created a simplified solution for you:

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

所以您可以看到-基本中没有任何内容被调用;

So you can see - nothing in base is called; simply because that child object is "fully" mocked.

整个观点是:您的被测代码仅需要一个模拟即可;

The whole point is: your code under test simply requires one object of a certain type; and you know in advance whether that will be child1 or child2. So you just create a mock for that class; and use PowerMockito in order return that mock you just created.

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

For the record: I played with spies for some time; but they dont help here; and they are also not required!

这篇关于模拟使用Java中Powermockito提供基类引用的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆