【问题标题】:Spring DAO testingSpring DAO testing
【发布时间】:2015-09-11 19:05:17
【问题描述】:

我听说建议为每个 DAO 类创建单独的接口,以使其测试更容易。关于“为什么”这个问题的答案是关于通过测试一替换原始 DAO 实现的可能性。但是没有关于如何做到这一点的信息。

所以,我对如何做到这一点很感兴趣。

假设我们有简单的 DAO 接口:

public interface PersonDao {
    void add();
    ...
}

它的实现也很简单:

@Repository
public class PersonDaoImpl implements PersonDao {

   public void add() {
      // doing something
   }
}

我们怎样才能这样测试它:

public class PersonDaoTest {

   @Autowire
   FakePersonDao fakePersonDao;

   @Test
   public void addTest() {
      fakePersonDao.add();
   }
}

FakeDaoPersonDao 接口的第二个“测试”实现在哪里:

public class FakePersonDaoImpl implements PersonDao {

    public void add() {
        // doing something different
    }
}

嗯?

我们应该将@Autowired@Qualifier 结合使用,还是有更好的方法?

【问题讨论】:

  • 使用 Spring Data,它会自动提供实现。
  • @chrylis,它使用了我不喜欢与 Spring MVC 一起使用的 JPA;(因为它强制将实体和表单保持为不同的实体而不是单个实体
  • 如果你不想使用真正的实现,那么使用一个模拟框架,比如Mockito。不,我不认为你应该为每个不同的DAO创建一个接口。您可以改为创建一个用于读取 DAO、编写 DAO 等的接口。
  • 您可以使用 JPA 实体(或 MongoDB 文档,或其他东西)作为 Spring MVC 表单对象。如此紧密地结合通常不是最好的主意,但你可以。
  • @chrylis,关于嵌套实体的阻塞问题。由于它不能作为字段直接传递给控制器​​,因此它强制单独发送,使用 JPA 实体作为表单没有任何意义:(

标签: java spring testing dao


【解决方案1】:

当人们建议用模拟代替真正的 DAO 时,他们是在谈论测试使用 DAO 的层。所以如果你有一个服务层,测试可能看起来像

public class MyServiceTest {
    private MyServiceImpl objectUnderTest = new MyServiceImpl();
    private PersonDao fakePersonDao;
    @Before
    public void setUp() {
        fakePersonDao = new FakePersonDao(); // or define it using Mockito
        objectUnderTest.setPersonDao(fakePersonDao);
    }
}

通过这种方式,您可以使用需要测试的服务的功能,而无需依赖对 DAO 封装的任何资源的访问权。

【讨论】:

  • 感谢您的回答。我感兴趣的是是否必须为服务实现设置设置器,或者有一种方法可以使用注释或其他方式来解决这个问题?
  • @Codemaster 反射将是一种无需设置器的方法。
  • @Codemaster:您可以使用反射(Spring 对此有一个 ReflectionTestUtil)、构造函数参数或自定义 TestConfiguration 来自动连接测试的依赖项。通常不需要限定符。
猜你喜欢
  • 2012-04-06
  • 1970-01-01
  • 2011-01-27
  • 2014-08-24
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多