事务教程——测试回滚
Posted
技术标签:
【中文标题】事务教程——测试回滚【英文标题】:transaction tutorial - test rollback 【发布时间】:2014-07-01 08:07:06 【问题描述】:我正在尝试学习如何在 java spring 中使用事务。我是一个java新手,所以请多多包涵:-) 我试图在下面实现的单元测试是测试: 如果抛出运行时异常,则回滚。
我遇到的问题是 java.lang.NullPointerException?
好的。我已经删除了一些代码以帮助提高可读性
TutorialTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest
@Autowired
private Dao dao;
@Test
public void that_if_a_runtime_exception_is_thrown_transaction_rolledback()
User u = new User();
u.setUsername("FAIL_TEST");
u.setPhone("0161");
u.setEmail("FAIL_TEST@gmail.com");
//dao.addUser(u); // -- this will insert if uncommented out so I know it works
OuterService os = new OuterService();
os.addUserThrowError(u);
OuterService.java
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class OuterService
@Autowired
private Dao dao;
@Transactional
public void addUserThrowError(User user) throws RuntimeException
dao.addUser(user); // gives me a java.lang.NullPointerException?
throw new RuntimeException("This should roll back DB entry");
Bean 在
中声明AppConfig.java
@Configuration
@EnableTransactionManagement
@ComponentScan(value = "com.training.spring.tx.tutorial.dao",
"com.training.spring.tx.tutorial.service")
public class AppConfig
public DataSource dataSource()
// Create a BasicDataSource object and configure database
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/spring_training_tx");
dataSource.setUsername("training");
dataSource.setPassword("training");
return dataSource;
@Bean
public DataSourceTransactionManager transactionManager()
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
@Bean
public JdbcTemplate jdbcTemplate()
return new JdbcTemplate(transactionManager().getDataSource());
【问题讨论】:
Spring不参与new OuterService();
查看 Javadoc。 Spring 有非常好的文档。 @ContextConfiguration
是做什么的? Spring中如何声明bean?
嗨,我已经更新了问题以帮助改进它。我还从标题中删除了 spring。我已经包含了 beans 声明。
答案非常简单:Spring 不涉及 new OuterService();,因此不会将任何东西自动装配到该对象中。解释比较长。阅读 Spring IoC 文档,其中解释了所有这些。
我已经查看了文档,但我并没有更接近于弄清楚我需要做什么?根据您的回复,我认为我需要将 new OuterService() 与 beans 配置链接。上面的 bean 示例在 XML 中,而我被告知要学习的不是..
【参考方案1】:
首先,引用javadoc of @ContextConfiguration
@ContextConfiguration
定义了类级元数据,用于 确定如何加载和配置ApplicationContext
集成测试。
考虑您在OuterService
上的使用方式。看起来对吗? OuterService
是否用于加载和配置 ApplicationCOntext
以进行集成测试?除非我遗漏了一些重要的东西,否则答案是:不。
那么OuterService
是什么?这是某种服务。您似乎想将其用作 bean。什么是豆子? bean 是一个对象,其生命周期由 Spring 管理。这包括 bean 类的实例化、对象的初始化、后处理,最后是对象的销毁。
如果你这样创建对象
OuterService os = new OuterService();
则不涉及 Spring。您创建了对象,Spring 无法与之挂钩。因此,您不能期望 Spring 自动装配其字段
@Autowired
private Dao dao;
由于您还没有初始化该字段,它仍然是null
,这会导致NullPointerException
。
那么我们如何获得一个OuterService
bean, 由 Spring 管理?您可以为OuterService
声明@Bean
方法,或者使用@Component
或其任何特化注释OuterService
,然后对它所在的包进行组件扫描。然后将bean 注入使用它的任何其他bean。例如,
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest
@Autowired
private Dao dao;
@Autowired
private OuterService os;
然后您可以直接使用该变量。
【讨论】:
以上是关于事务教程——测试回滚的主要内容,如果未能解决你的问题,请参考以下文章