2017-05-31 357 views
1

我已经Spring类说时的Mockito()。在龙目岛@RequiredArgsConstructor(onConstructor = @__(@自动装配Autowired))使用的

@Component 
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) 
class MainServiceImpl implements MainService { 
    private final InternalService internalService; 

    public Set<String> do(String anything) { 
     Set<String> relevent = internalService.finaIntern(anything); 
     return relevent; 
    } 
} 

我写单元测试情况下,预期thenReturn()不行为如下

@RunWith(MockitoJUnitRunner.class) 
class TestMainServiceImpl { 

    @InjectMocks 
    private MainServiceImpl service; 

    @Mock 
    InternalService internalService; 

    @Before 
    public void init(){ 
     MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void testDo() { 
     Set<String> setData = new HashSet<>(); 
     setData.add("ABC"); 
     String a ="a"; 
     when(internalService.finaIntern(any(String.class)) 
            .thenReturn(setData); 
     Set<String> result = service.do(a); 
     assertTrue(!result.isEmpty()); 
    } 

} 

这里我的测试用例失败,但如果我删除最终形式MainServiceImpl,做一个明确的@Autowired像下面

@Component 
class MainServiceImpl implements MainService { 
    @Autowired 
    private InternalService internalService; 
    ..... 

在这里,我很想知道 1.如何在我的测试情况下通过,如果我删除final关键字 2.是否使用@RequiredArgsConstructor一个很好的做法,如果是,那么如何,如果没有那么也是为什么?

预先感谢

+0

您的测试没有意义...您正在创建一个模拟并将其注入到测试用例中,而不是“MainServiceImpl”。因此,无论您是使用代码还是显示代码,或者您的代码都是真正的代码。 –

+0

@ M.Deinum由于安全原因,我无法在这里发布实际的代码,所以我输入了类似的类。这是一个错字错误,我修改了它。 – MishraJi

+0

你也有一个double init,你已经使用'MockitoJUnitRunner'运行,但是再次在你的'@ before'方法中初始化它们。你最先创建他们(特别是由于你的最终成员)。 –

回答

2

它无关lombok也不春@Autowired@RunWith(MockitoJUnitRunner.class)MockitoAnnotations.initMocks(this);相结合的问题。删除其中的任何内容和行为如预期。你不需要他们两个。实际上MockitoAnnotations.initMocks(this);仅适用于您不能使用@RunWith(MockitoJUnitRunner.class)时的情况,例如,如果您需要使用SpringRunner.class

这是为什么它不起作用。 首先你的对象被实例化。因此,无论您是创建和注入你@InjectMock对象@Mock

下面你可以看到,新创建模拟(mocks[0]),serviceinjectIntomock里面是同一个对象。

enter image description here

但随后的初始化发生第二次。 所以mockito创建一个新的@Mock对象,并试图将它注入到已经实例化的@InjectMock对象中。但是只要它是最终的,就没有把它注入现场。 所以这是我们第二初始化后:

enter image description here 正如你可以看到,现在正在测试注入到你的对象你testClassInstance和模拟内部的模拟对象是不同的。

@RequiredArgsConstructor怎么样:对我来说,完全可以像你一样使用它。