字段注入在Spring Data存储库的测试类中是否合法?

时间:2017-09-07 11:03:16

标签: java spring dependency-injection spring-data

我想为Spring Data存储库编写集成测试,并想知道在测试类中使存储库可用的首选方法是什么。

在测试我自己的普通旧服务时,我使用这样的东西来避免使用字段注入,因为不应该使用字段注入according to Spring Data project lead Oliver Gierke

public class myServiceTest {

   private MyService myService;

   @Before
   public void setUp() {
       myService = new MyService();
   }

   [...]
}

但Spring Data存储库被定义为没有实现的接口,因为Spring魔法会动态创建实现。

public interface FruitRepository extends CrudRepository<Fruit, Long> {

    List<Fruit> findByName(String name);
}

因此我没有像这样使用的构造函数。

使用构造函数注入(如下面的示例)也不起作用,因为在尝试运行测试时会产生异常:

@Autowired
public MyServiceTest(MyService myService) {
    this.myService = myService;
}

java.lang.Exception: Test class should have exactly one public zero-argument constructor

据我所知,我留下的唯一选择是通过字段注入注入存储库,如下面的工作示例所示:

@RunWith(SpringRunner.class)
@SpringBootTest
public class FruitRepositoryTest {

    @Autowired
    private FruitRepository fruitRepository;

    @Test
    public void findByNameFindsAnExistingFruit() {

        fruitRepository.deleteAll();
        fruitRepository.save(new Fruit("Orange"));
        List<Fruit> foundFruits = fruitRepository.findByName("Orange");

        assertFalse(foundFruits.isEmpty());
    }

    @Test
    public void findByNameDoesNotFindANonExistingFruit() {

        fruitRepository.deleteAll();
        fruitRepository.save(new Fruit("Apple"));
        List<Fruit> foundFruits = fruitRepository.findByName("Orange");

        assertTrue(foundFruits.isEmpty());
    } 
}

所以,我的问题是:这是规则的合法例外,以避免现场注入或我错过了什么?或者我是否可能过度思考这一点,因为无论如何现场注入都可以在测试类中使用?

1 个答案:

答案 0 :(得分:1)

对于测试,这非常好。

  1. 使用当前版本的JUnit,实际上没有合理的方法可以采用不同的方式。

  2. 更喜欢构造函数注入的一点是,其他代码片段可以在不使用任何反射魔法的情况下正确实例化类。但除了JUnit之外,没有人会尝试实例化你的测试,所以论证是无效的。

  3. Spring Data本身的集成测试使用这种方法。例如,请参阅https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java#L97请注意,Oliver是作者之一,所以我猜他也同意。