由于构造函数中的静态类,Mockito无法使用@InjectMocks创建实例

时间:2018-08-03 14:51:31

标签: java unit-testing mockito junit4 powermockito

我必须用一些代码进行单元测试(不是我写的),但是我被困在一个地方。 我正在使用Powermock和Mockito。 因此,问题在于@InjectMocks甚至在测试方法之前都调用默认构造函数,在默认构造函数内部,他们使用了静态类和setter来设置字段,因此使用@Inject注入模拟无法创建实例。是否可以通过更改API代码来解决此问题?

    RunWith(PowerMockRunner.class)
    @PrepareForTest(UserGroup.class)
    public class SomeServiceImplTest {

    @Mock
    private SomeDAOImpl SomeDAOImpl;


    @Mock
    private UserGroup userGroup;


    @InjectMocks
    SomeServiceImpl someServiceImpl;


    @Test
    public void testSomeMethod(){
         String username = "UserToBeTest";
     //Some code

     //     
         verify(SomeDAOImpl).saveUserGroup(any(),any());
     }
}






public class SomeServiceImpl {

private SomeDAOImpl someDAOImpl;
private SomeIndex someIndex;
public void setSomeDAOImpl(SomeDAOImpl someDAOImpl) {
    this.someDAOImpl = someDAOImpl;
}

    public SomeServiceImpl (){
     someIndex; = AFinalClass.init();
     setSomeDAOImpl(new SomeDAOImpl())  
   }
}

我想防止SomeServiceImpl()被调用。请让我知道是否有任何方法可以解决此问题。 我可以模拟构造函数吗-但是SomeServiceImpl()在testSomeMethod()之前被调用。

1 个答案:

答案 0 :(得分:0)

围绕静态方法调用的通常解决方案是引入一个Factory。

代替

public class Example {
    private void foo() {
        Instant now = Instant.now();
    }
}

使用

public class Example {

    private final Supplier<Instant> instantSupplier;

    public Example(Supplier<Instant> instantSupplier) {
        this.instantSupplier = instantSupplier;
    }

    public void foo() {
        Instant now = instantSupplier.get();
        System.out.println(now);
    }
}

现在,您可以模拟Instant的创建。

@RunWith(MockitoJUnitRunner.class)
public class ExampleTest {

    @Mock
    Supplier<Instant> instantSupplier;

    @Test
    public void test() {
        Instant myNow = Instant.parse("2007-12-03T10:15:30.00Z");
        when(instantSupplier.get()).thenReturn(myNow);

        new Example(instantSupplier).foo();
    }

}

输出:

  

2007-12-03T10:15:30Z