我正在使用Spring 4.0.7,并且正在使用JUnit进行测试。
关于DI Spring提供@Autowired
在三个地方使用
我总是首先解决这两个问题,为什么从来没有第三个选项?
因为我记得早就读过不应该使用场注射,因为它对测试有负面影响。 JUnit失败了。
注意:仅针对测试是问题所在。对于运行时或生产一切顺利
目标:出于演示/学术目的,我想产生这个问题。
我有以下内容:
存储库
public interface PersonRepository extends JpaRepository<Person, String>{
}
服务
@Service
@Transactional
@Profile("failure")
public class PersonFailTestServiceImpl implements PersonService {
private static final Logger logger = ...
@Autowired
private PersonRepository personRepository;
其他服务(致电或使用上述服务)
@Service
@Transactional
@Profile("failure")
public class PersonFailTestProcessImpl implements PersonProcess {
private static final Logger logger = ...
@Autowired
private PersonService personService;
如何看待这两种服务基于Field Injection。
现在测试:
如何加载bean
@Configuration
@ComponentScan( basePackages={"com.manuel.jordan.server.infrastructure"},
basePackageClasses={PersonProcess.class,PersonRepository.class, PersonService.class})
public class CentralConfigurationEntryPoint {
}
@ContextConfiguration(classes=CentralConfigurationEntryPoint.class)
public class CentralTestConfigurationEntryPoint {
}
现在有两个测试类
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"development","failure"})
public class PersonServiceImplDevelopmentFailureTest extends CentralTestConfigurationEntryPoint {
@Autowired
private PersonService personService;
@Test
public void savePerson01(){
Person person01 = PersonFactory.createPerson01();
personService.save(person01);
personService.printPerson(personService.findOne("1"));
}
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"development","failure"})
public class PersonProcessImplDevelopmentFailureTest extends CentralTestConfigurationEntryPoint{
@Autowired
private PersonProcess personProcess;
所有测试方法都通过,全部为绿色。我不知道我是否遗漏了某些东西,或者通过Spring 4解决了问题
答案 0 :(得分:2)
如果这是你的前提或问题
那时你想错了。使用字段注入没有任何内在错误,绝对不会导致JUnit测试失败。如果bean存在,Spring将能够注入它,无论它是在构造函数,setter方法还是字段中。因为我记得早就读过有关野外注射的内容 不应该使用,因为它有负面影响 测试。 JUnit失败了。
由于您已激活failure
个人资料,因此将找到您的PersonFailTestServiceImpl
bean。
答案 1 :(得分:1)
我想我可以提供帮助。您在此处发布的示例代码是系统/集成测试的一个很好的示例,而不是UNIT测试。
如果您是UNIT测试PersonFailTestProcessImpl,则必须通过代码自行设置personRepository依赖项。但它是私人的,所以你怎么做?您不能使用构造函数或setter,因为没有提供。这就是“难以进行单元测试”的意思。
Java 5+提供了一种通过反射(所谓的特权访问器)设置这样的私有变量的方法。基本上,您获取类,获取声明的字段,调用其setAccessible方法,然后您可以直接设置其值。有些库会为您执行这些步骤,但关键是与X.setSomething()相比,这是一个痛苦;
因此,在私有字段上使用@Autowired没有任何“使jUnit失败”。但是,构建没有用于建立依赖关系的构造函数或setter的对象模型是不必要的约束。