[英]JUnit&Mockito: how to inject field values to Spring component?
I'm trying to test Spring @Repository
component but first I've to inject table name to let this work properly. 我正在尝试测试Spring
@Repository
组件,但首先我必须注入表名以使其正常工作。
Here's what I made. 这就是我做的 It's simple DAO:
这是简单的DAO:
@Repository
@Transactional
public class AccountDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
private String table = "accounts"; <-- I need to inject this value from tests
...
}
the unit test: 单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-web-servlet.xml")
@Transactional
public class AccountDaoTest {
@Autowired
private AccountDAO accountDAO;
@Before
public void init() {
accountDAO = Mockito.spy(accountDAO);
ReflectionTestUtils.setField(accountDAO, "table", "accounts_test");
}
...
}
The problem is that ReflectionTestUtils
ignores field assignment and accountDAO
still uses accounts
table name value instead of accounts_test
. 问题是,
ReflectionTestUtils
忽略字段赋值和accountDAO
仍然使用accounts
表名值,而不是accounts_test
。
How can I round this problem? 我该如何解决这个问题?
You can use two techniques to change the table name stored in private variable: 您可以使用两种技术来更改存储在私有变量中的表名:
ReflectionTestUtils
without mockito spying. ReflectionTestUtils
。 But this is not very reliable integration testing, because when somebody changes table
schema, your test wouldn't catch the problem. 但这不是一个非常可靠的集成测试,因为当有人更改
table
架构时,您的测试将无法解决问题。 There are ways how to tackle such problem: 有一些方法可以解决此类问题:
Here, your want to separate real database and integration test database. 在这里,您要分离真实数据库和集成测试数据库。 Your goal is to test that DAO layer works well.
您的目标是测试DAO层是否运作良好。 I suggest to remove completely Mockito and use DBUnit for instance.
我建议完全删除Mockito并使用DBUnit作为实例。
Then, you keep your DAO, Spring an JUnit. 然后,保留DAO,并生成一个JUnit。 Injecting another table name is not necessary.
不需要注入另一个表名。
DBUnit allows you to create a small database only used for testing according to a XML dataset. DBUnit允许您创建一个仅用于根据XML数据集进行测试的小型数据库。
Something like this: 像这样:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
@DatabaseSetup("my-dbunit-dataset.xml")
public class AccountDAOTest {
@Autowired
private AccountDAO accountDAO;
@Test
public void findAllAccounts() {
assertThat(accountDAO.findAll().size(), is(2));
}
}
my-dbunit-dataset.xml : my-dbunit-dataset.xml:
<dataset>
<account id="1" value1="foo" />
<account id="2" value1="bar" />
</dataset>
DBunit is really powerfull. DBunit确实功能强大。 You can find the official link here :
您可以在此处找到官方链接:
http://dbunit.sourceforge.net/howto.html DbUnit - Getting started http://dbunit.sourceforge.net/howto.html DbUnit-入门
You can also define a setter method for table
field: 您还可以为
table
字段定义setter方法:
protected void setTable(String pTableName) this.table = pTableName; }
and invoke the setter in the test class before()
method. 并在测试类的
before()
方法中调用设置器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.