【问题标题】:unit testing service layer that uses hibernate and annotations, and no DAO使用休眠和注释的单元测试服务层,没有DAO
【发布时间】:2012-02-13 16:02:48
【问题描述】:

对以下内容进行单元测试/集成测试的最佳方法是什么:

@Service("fooService")
public class FooService {

  @Resource(name = "sessionFactory")
  private SessionFactory sessionFactory;

  /*** Get all **/
  @Transactional(readOnly = true)
  public List<Foo> getAllFoos() {
    final Session session = sessionFactory.getCurrentSession();
    final Criteria crit = session.createCriteria(Foo.class);
    return crit.list();
  }
}

我很高兴使用 mockito,但不确定如何利用它的用处。我见过的大多数情况都需要将 dao/mock dao 作为方法参数传入。

显然,我会推断出更复杂的方法。

【问题讨论】:

  • 这就是 dao - 仅仅因为它的名字有服务并不能让它如此。模拟 Session 等并没有什么好处——除非你有很多逻辑。我会针对内存数据库运行集成测试。
  • @BedwyrHumphreys 我称它为服务是因为我在其中放置了很多应用程序逻辑(显然这种方法相当简单),并且只需使用 hibernate 来完成所有正常的 dao 工作(保存、更新、选择,删除),并没有真正看到为访问休眠会话的〜2行创建整个dao层的意义。所以你认为加载一个应用程序上下文并在不模拟任何东西的情况下对 db 运行测试是要走的路吗?
  • 绝对 - 想想你在这里要测试什么:这些方法是否从数据库返回它们应该返回的内容。在这里模拟会话和标准没有多大意义。
  • 是的,我本来就是这么想的,谢谢。

标签: java hibernate spring unit-testing integration-testing


【解决方案1】:

这个类是 DAO,从模拟 Session 等中没有什么好处,除非你有很多逻辑——如果你这样做了,那么它可能会更好地放在实际的服务类或模型本身中。

想想你在这里要测试什么:这些方法是否从数据库返回它们应该返回的内容。我会针对内存数据库运行集成测试。

【讨论】:

    【解决方案2】:

    如果您将@Resource 注解放在一个方法上,那么使用 SessionFactory 的模拟实现来设置测试和配置服务会容易得多(如果这是您所要求的)。

    @Service("fooService")
    public class FooService {
    
      private SessionFactory sessionFactory;
    
      @Resource(name = "sessionFactory")
      public void setSessionFactory(SessionFactory sessionFactory) {
         this.sessionFactory = sessionFactory;
      }
    
    }
    

    【讨论】:

    • 不需要加入一个方法,但您希望公开SessionFactory的构造函数或设置器
    【解决方案3】:

    我认为你有几件事要决定:

    • 是否将 sessionFactory 保留为字段。我想你应该这样做。
    • 是否使用构造函数或设置器注入。我更喜欢构造函数注入。
    • 您将如何模拟 SessionFactory:手动编写、使用 Mockito、EasyMock ... 随心所欲。

    【讨论】:

      猜你喜欢
      • 2011-05-01
      • 2019-08-06
      • 1970-01-01
      • 2011-06-19
      • 2012-01-25
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多