我有一个简单的服务,我用默认用户预填充user
db表。该服务如下所示:
@Service
public class BootstrapService
{
@Autowired
UserRepository userRepository;
public void bootstrap()
{
User user = new User("admin", "password");
userRepository.save(user);
}
}
我在应用程序启动时使用ApplicationListener
:
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent>
{
@Autowired
private BootstrapService bootstrapService;
@Override
public void onApplicationEvent(final ApplicationReadyEvent event)
{
bootstrapService.bootstrap();
}
}
现在我想为BootstrapService
编写一个单元测试来检查是否真的添加了用户,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@Transactional
public class BootstrapServiceTests
{
@Autowired
private UserRepository userRepository;
@Autowired
private BootstrapService bootstrapService;
@Test
public void testBootstrap()
{
bootstrapService.bootstrap();
assertEquals(1, userRepository.count());
}
}
然而,会发生的事情是bootstrapService.bootstrap()
函数被调用两次 - 一次由ApplicationListener
调用,一次由测试本身调用,导致两个用户被添加到数据库中。
如何在运行测试时阻止ApplicationListener#ApplicationReadyEvent
被触发?
答案 0 :(得分:2)
如评论中所述,您可以尝试模拟监听器(但我不确定它是否可以在这种精确的情况下工作)。我能想到的其他方式(这是肯定的)是使用Spring配置文件,以排除ApplicationStartup在测试配置文件中运行,如下所示:
@Component
@Profile("!test")
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent>
然后,当您运行测试时,只需使用环境开关:--spring.profiles.active=test
缺点是ApplicationStartup将在每次使用“test”配置文件的测试中排除。
答案 1 :(得分:0)
如果您使用的是@EventListener
@EventListener(
value = ApplicationReadyEvent.class,
condition = "@environment.getActiveProfiles()[0] != 'test'")
public void onStartup() throws IOException {}