【问题标题】:Spring JUnit testing with @Autowired annotation使用 @Autowired 注解的 Spring JUnit 测试
【发布时间】:2012-01-19 05:31:52
【问题描述】:

在其中一个被测类中引入@Autowired 后,我的测试用例出现了问题。

我的测试用例现在看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml", "/spring-security.xml"})
public class StudentRepositoryTest extends AbstractDatabaseTestCase {

private StudentRepository studentRepository;
private CompanyRepository companyRepository;
private Student testStudent;
private Company testCompany;

@Before
public void setUp() {
    studentRepository = new StudentRepository();
    studentRepository.setJdbcTemplate(getJdbcTemplate());
    testStudent = Utils.testStudentNoApplication();
}
@Test
....

}

StudentRepository 现在看起来像这样:

@Service
public class StudentRepository extends AbstractRepository<Student> {

...

private PasswordEncoder passwordEncoder;
private MailService mailService;

public StudentRepository() {
    // TODO Auto-generated constructor stub
}

@Autowired 
public StudentRepository(MailService mailService, PasswordEncoder passwordEncoder) {
    this.mailService = mailService;
    this.passwordEncoder = passwordEncoder;
}

显然,这个测试用例不再有效。 但是我需要对测试用例进行哪些更改才能让测试用例拾取@Autowired 注释?

编辑:

我现在已将我的 setUp() 更新为此(我需要密码编码器以避免空密码):

@Before
public void setUp() {
    //studentRepository = new StudentRepository();
    studentRepository = new StudentRepository(mock(MailService.class), ctx.getAutowireCapableBeanFactory().createBean(ShaPasswordEncoder.class));
    studentRepository.setJdbcTemplate(getJdbcTemplate());
    testStudent = Utils.testStudentNoApplication();
}

我的测试用例现在运行正常,但我的测试套件因 NullPointerException 而失败。 我猜 ApplicationContext 在运行测试套件时由于某种原因没有被自动装配?

【问题讨论】:

  • 这只是测试中的问题吗? Spring 是否会因异常而以某种方式失败?
  • 如果是单元测试,您可能应该将模拟 MailService 和 PasswordEncoder 实例传递给 StudentRepository 的构造函数。查看 Mockito、EasyMock 或任何其他模拟 API。

标签: spring unit-testing junit


【解决方案1】:

如果您不想在@ContextConfiguration 引用的XML 文件之一中声明您的StudentRepository 并将其自动装配到测试中,您可以尝试使用AutowireCapableBeanFactory,如下所示:

...
public class StudentRepositoryTest extends AbstractDatabaseTestCase {
    ...
    @Autowired ApplicationContext ctx;

    @Before
    public void setUp() {
        studentRepository = ctx.getAutowireCapableBeanFactory()
                               .createBean(StudentRepository.class);
        ...
    }
    ...
}

【讨论】:

  • 谢谢,这行得通,或者至少效果更好。我遇到了一个新异常(UnsatisfiedDependency),但正如 JB Nizet 在上面的评论中提到的那样,我可能应该将模拟传递给构造函数。
  • @Daniel:是的,我的解决方案假定MailServicePasswordEncoder@ContextConfiguration 引用的配置中声明,并且您想针对它们进行测试。如果您需要模拟,请使用模拟。
  • 有些成功,但仍有一些问题。我已经更新了我的第一篇文章。
  • 原来我在测试套件中使用了 JUnit3 风格的测试,它没有检测到测试类中的注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多