为什么我的stubbed方法返回null?

时间:2015-08-17 14:55:39

标签: java mockito stub inject

我有一个班级Dummy。我注入3个变量。但是,其中一个不能注射,因为它是一个界面。所以我注入一个对象,其中一个方法返回所需的类型。

Class Dummy
{
   private final Class1 class1;
   private final Class2 class2
   private final Interface1 interface1;

  @Inject
  Dummy(Class1 class1, Class2 class2, HelperClass helperclass) 
  {
       this.class1 = class1;
       this.class2 = class2;
       this.interface1 = helperclass.somefunction();
  }
}

HelperClass的{​​{1}}会返回somefunction的实例。

这是我的测试:

Interface1

但是,运行测试时@RunWith(MockitoJUnitRunner.class) Class DummyTest { @Mock private Class1 class1; @Mock private Class2 class2; @Mock private HelperClass helperclass; @InjectMocks private Dummy dummy; @Before public void start() { Interface1 mockInterface = mock(Interface1.class); when(helperclass.somefunction()).thenReturn(mockInterface); } @Test public void test() { // etc... } } 为空。我做错了什么?

1 个答案:

答案 0 :(得分:6)

@InjectMocks发生在@Before注释之前。

出于这个原因(以及other reasons),我建议完全不使用@InjectMocks ;只需使用真正的构造函数在@Before方法中构建SUT类。

当您向测试类添加一些print语句时,此顺序很明显。我删除了所有Class1Class2内容,因为它们不相关。请参阅此代码运行:

@RunWith(MockitoJUnitRunner.class)
public class DummyTest {
  @Mock
  private HelperClass helperclass;

  @InjectMocks
  private Dummy dummy;

  @Before
  public void start() 
  {
    System.out.println("In @Before!");
    Interface1 mockInterface = mock(Interface1.class);
    when(helperclass.somefunction()).thenReturn(mockInterface);
  }

  @Test
  public void test()
  {
    System.out.println("In @Test!");
  }

  public static class Dummy {
    public final Interface1 interface1;
    public final HelperClass helperclass;

   @Inject
   Dummy(HelperClass helperclass) 
   {
     System.out.println("In dummy constructor!");
        this.interface1 = helperclass.somefunction();
        this.helperclass = helperclass;
   }
 }

  private static class HelperClass {
    Interface1 somefunction() {
      return new Interface1() {};
    }
  }

  private static interface Interface1 {

  }
}

输出:

In dummy constructor!
In @Before!
In @Test!

如果您坚持使用@Mock@InjectMocks,则可以尝试使用answer参数:

@Mock(answer=Answers.RETURNS_MOCKS)

会使helperclass.somemethod()返回模拟而不是null

老实说,它以这种方式工作并不奇怪。 Mockito的作者真的不喜欢Partial Mocks / Stubs,并且明确地这样说in their documentation

  

像往常一样,您将阅读部分模拟警告:通过将复杂性划分为单独的特定SRPy对象,面向对象编程更不能解决复杂性问题。部分模拟如何适应这种范式?好吧,它只是没有...部分模拟通常意味着复杂性已被移动到同一对象上的不同方法。在大多数情况下,这不是您想要设计应用程序的方式。

     

然而,在极少数情况下,部分模拟很方便:处理代码无法轻易更改(第三方接口,遗留代码的临时重构等)但是,我不会使用部分模拟新的,测试驱动的&安培;精心设计的代码。

helperclass返回null以外的内容是部分模拟,因此他们不会喜欢它。