2016-03-10 139 views
3

我有一个春天托管的应用程序,我喜欢我的服务层被嘲笑。所以我创建了一个Spring应用程序Java配置并返回了实际服务的模拟。春天试图autowire Mockito嘲笑

对于e.g,

@Bean 
@Profile("resource") 
public MyService mockService() { 
    return mock(MyService.class) 
} 

然后是为MyService竟把

class MyService { 

    @Autowired 
    private MyDao dao; 
} 

当春天创建一个name "mockService"的豆,它也试图自动装配的模拟MyDao?这在我看来打败了嘲笑的目的。这是预期的行为,解决方法是什么?

+2

不要嘲笑课程。该模拟仍然是一个带有所有注释和类信息的MyService。你使它成为一个bean,所以它仍然会扫描并检测注释。 –

+0

计数器建议:考虑在测试运行期间不要加载弹簧。 具体而言,请勿使用@RunWith(SpringJunit ...)注释。 你应该能够使用Mockito模拟单元测试的类使用的所有东西,然后运行实际的单元测试。 – DwB

+0

感谢这两个答案,他们两个都有道理,编码到界面可能会解决问题。虽然 –

回答

1

所以底线,它的最佳实践编写接口而不是具体的类特别是如果你想要写在特定层集中测试。

0

好吧,我想你想执行一个集成测试,但使用一些模拟考试,做这样的事情:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = {Application.class, YourMockConfigurationClass.class}) 
@WebIntegrationTest 
public class MyIntegrationTest { 
    ... 
} 

在这种情况下,你可以创建你的服务的实体模型,并告诉这个服务实例有优先权的弹簧:

@Bean 
@Primary 
public MyService mockService() { 
    return mock(MyService.class) 
} 

这样做,每当Spring必须注入一个不合格的MyService实例时,它总是选择你的模拟。但它并不妨碍Spring创建原始服务。

所以在Spring环境中会有MyService这两个实例,模拟实例和原始实现。但是使用@Primary你告诉Spring你的模拟具有优先权。另一方面,为了防止Spring在你的环境中加载任何模拟(开发,测试等),你应该用一个测试@Profile或者一个自定义注释来注释你的模拟配置类(比如@MockBean),然后配置你的组件扫描策略,不会加载这个类(@ComponentScan(excludeFilte[email protected](MockBean.class))

+0

谢谢,但我认为在我的情况下,标记为Primary并不能解决问题。 Deinum指出,它仍然是一个带注释的类。顺便说一句,我的配置类标有@Profile。所以答案是总是代码接口,而不是具体的类 –

+0

好的。我假设你正在使用接口。 – jfcorugedo