模拟抽象类并向其注入Mockito注释? [英] Mocking an abstract class and injecting classes with Mockito annotations?

查看:365
本文介绍了模拟抽象类并向其注入Mockito注释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以模拟一个抽象类,并使用Mockito注释将其注入模拟类。我现在有以下情况:

Is it possible to both mock an abstract class and inject it with mocked classes using Mockito annotations. I now have the following situation:

@Mock private MockClassA mockClassA;
@Mock private MockClassB mockClassB;

@Mock(answer = Answers.CALLS_REAL_METHODS) private AbstractClassUnderTest abstractClassUnderTest;

@Before
public void init() {
    MockitoAnnotations.initMocks(this);
    Whitebox.setInternalState(abstractClassUnderTest, mockClassA);
    Whitebox.setInternalState(abstractClassUnderTest, mockClassB);
}

我想在AbstractClassUnderTest上使用类似@InjectMocks的方法,但可以不能与@Mock结合使用。使用Powermock的Whitebox可以解决当前的问题,但是我很好奇是否有可能仅通过注释来解决它。我找不到任何解决方案或示例。

I'd like to use something like @InjectMocks on AbstractClassUnderTest but it can't be used in combination with @Mock. The current situation, with Whitebox from Powermock, works but I'm curious if it's possible to solve it with just annotations. I couldn't find any solutions or examples.

(我知道测试抽象类的异议,我个人宁愿测试具体的实现,而只使用@InjectMocks 。)

(I know about the objections to test abstract classes and I'd personally rather test a concrete implementation and just use @InjectMocks.)

推荐答案

出于一个明显的原因,我不知道有任何解决方法:@InjectMocks用于非-mocked系统进行测试,而@Mock是为模拟协作者设计的,而Mockito并不是为任何类设计的,以在同一测试中同时扮演这两个角色。

I am not aware of any way to go about this, for one clear reason: @InjectMocks is meant for non-mocked systems under test, and @Mock is meant for mocked collaborators, and Mockito is not designed for any class to fill both those roles in the same test.

请注意,您的 @Mock(CALLS_REAL_METHODS)声明是内在的危险:您正在测试AbstractClassUnderTest,但没有运行任何构造函数或初始化任何字段。我认为,无论哪种注释可以为您提供帮助或不能为您提供帮助,使用这种设计进行的测试都不会是现实或可靠的。 (就我个人而言,我以前赞成将抽象类的真正部分模拟作为工具箱中的工具,但我开始认为它们与现实相距太远而无用。)

Bear in mind that your @Mock(CALLS_REAL_METHODS) declaration is inherently dangerous: You're testing your AbstractClassUnderTest, but you are not running any constructors or initializing any fields. I don't think you can expect a test with this design to be realistic or robust, no matter what annotations can or cannot do for you. (Personally, I was previously in favor of real partial mocks of abstract classes as a "tool in the toolbox", but I'm coming around to thinking they're too far removed from reality to be useful.)

如果我处于您的位置,我将创建一个小的替代实现进行测试:

Were I in your position, I would create a small override implementation for testing:

@RunWith(JUnit4.class) public class AbstractClassTest {
  /** Minimial AbstractClass implementation for testing. */
  public static class SimpleConcreteClass extends AbstractClass {
    public SimpleConcreteClass() { super("foo", "bar", 42); }
    @Override public void abstractMethod1() {}
    @Override public String abstractMethod2(int parameter) { return ""; }
  }

  @InjectMocks SimpleConcreteClass classUnderTest;
  @Mock mockClassA;
  @Mock mockClassB;
}

此时,您已经有了一个简单且可预测的AbstractClass实现,您可以如果您只想测试AbstractClass具有与以前相同的扩展API,则即使没有模拟框架也可以使用。 (这是对抽象类经常被忽视的测试。)您甚至可以提取它,因为它可能对其他测试很有用:如果要覆盖单个测试类的抽象行为,则可以使用以下方法创建匿名内部类:只需设置一个方法即可,或者可以设置 classUnderTest = spy(classUnderTest); 来设置Mockito代理以及所需的行为。

At this point, you have a simple and predictable AbstractClass implementation, which you can use even without a mocking framework if you just wanted to test that AbstractClass has the same API for extension that it did before. (This is an often-overlooked test for abstract classes.) You can even extract this, as it may be useful for other testing: Should you want to override the abstract behavior for a single test class, you can create an anonymous inner class with just a single method override, or you can set classUnderTest = spy(classUnderTest); to set up Mockito proxying and the behavior you want.

(请记住,@ InjectMocks和@Spy不能可靠地一起使用,如此GitHub问题及其链接到的Google代码和邮件列表线程。)

(Bear in mind that @InjectMocks and @Spy can't be used reliably together, as documented in this GitHub issue and the Google Code and mailing list threads to which it links.)

这篇关于模拟抽象类并向其注入Mockito注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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