如何将mock注入到具有@Transactional的@Service中
我在我的unit testing中有任何问题,我有类似的东西。 如果使用Transactional注释blargh
函数,则会在blargh
上覆盖模拟注入。 如果我删除了Transactional,那么模拟就会停留在那里。 通过观察代码,当服务中的函数使用transactinal进行注释时,Spring似乎懒洋洋地加载服务,但是当服务中的函数没有进行注释时,它会急切地加载服务。 这会覆盖我注入的模拟。
有一个更好的方法吗?
@Component public class SomeTests { @Autowired private SomeService someService; @Test @Transactional public void test(){ FooBar fooBarMock = mock(FooBar.class); ReflectionTestUtils.setField(someService, "fooBar", fooBarMock); } } @Service public class someService { @Autowired FooBar foobar; @Transactional // <-- this causes the mocked item to be overridden public void blargh() { fooBar.doStuff(); } }
您可以尝试以下列方式实施测试:
@Component @RunWith(MockitoJUnitRunner.class) public class SomeTests { @Mock private FooBar foobar; @InjectMocks private final SomeService someService = new SomeService(); @Test @Transactional public void test(){ when(fooBar.doStuff()).then....; someService.blargh() ..... } }
我现在无法尝试,因为没有您的配置和相关代码。 但这是测试服务逻辑的常用方法之一。
使用Spring @Profilefunction – bean可以与某个组相关联,并且可以通过注释激活或停用该组。
查看此博客文章和文档以获取更详细的说明,这是如何定义生产服务和两组模拟服务的示例:
@Configuration @Profile("production") public static class ProductionConfig { @Bean public InvoiceService realInvoiceService() { ... } ... } @Configuration @Profile("testServices") public static class TestConfiguration { @Bean public InvoiceService mockedInvoiceService() { ... } ... } @Configuration @Profile("otherTestServices") public static class OtherTestConfiguration { @Bean public InvoiceService otherMockedInvoiceService() { ... } ... }
这是如何在测试中使用它们:
@ActiveProfiles("testServices") public class MyTest extends SpringContextTestCase { @Autowired private MyService mockedService; // ... } @ActiveProfiles("otherTestServices") public class MyOtherTest extends SpringContextTestCase { @Autowired private MyService myOtherMockedService; // ... }