2017-03-10 41 views
0

这是我第二次尝试使用MyBatis创建集成测试。我尝试了很多东西,但似乎没有解决这个问题的方法。希望你们能帮助我。如何使用Arquillian(PART2)模拟MyBatis映射器接口?

In my previous question我试着写一个集成测试来检查我的rest API的输出。其中的场景如下:rest API调用注入的EJB,它使用MyBatis执行一些SQL:rest api> ejb> mybatis。遗憾的是我没能既不注入,也不是模拟的MyBatis映射器接口,所以我的测试不工作:(

现在我创造了另一个测试场景,但我在相同的情况下结束了 现在我的情况是疯狂容易。我。有注入MyBatis的映射器的EJB,我想用的Arquillian嵌入式Glassfish的/似鲭水狼牙鱼服务器中测试

这是我的例外:

org.glassfish.deployment.common.DeploymentException: CDI deployment failure:WELD-001408: Unsatisfied dependencies for type AccountDao with qualifiers @Default 
    at injection point [BackedAnnotatedField] @Inject private a.b.c.AppleBean.accountDao 
    at a.b.c.AppleBean.accountDao(AppleBean.java:0) 

EJB:

@Stateless 
public class AppleBean { 
    @Inject 
    private AccountDao accountDao; 

    public String say() { 
     return "Apple"; 
    } 
} 

帐户maper(DAO):

@Mapper 
public interface AccountDao { 

    @Select("SELECT * FROM account WHERE id = #{id}") 
    @Results({ 
      @Result(property = "email", column = "email", javaType = String.class), 
      @Result(property = "firstName", column = "first_name", javaType = String.class), 
      @Result(property = "lastName", column = "last_name", javaType = String.class), 
    }) 
    Account findById(@Param("id") Long id); 
} 

我的测试类:

@RunWith(Arquillian.class) 
public class AppleBeanTest { 
    @EJB 
    private AppleBean bean; 

    @Deployment 
    public static WebArchive createDeployment() { 
     return ShrinkWrap 
       .createFromZipFile(WebArchive.class, new File("target/war-demo-test-1.0.war")) 
       .addPackages(true, "a.b"); 
    } 

    @Test 
    public void say() throws Exception { 
     assertNotNull(bean); 
     System.out.println(bean.say()); 
    } 
} 

如果我评论在AppleBeanTest两行删除refelence到MyBatis的映射器那么我的测试工作正常。

I uploaded the source code to github as well.


SOLUTION

下面的类是从我的测试遗漏。 @blackwizard感谢你让我走向正确的方向。

SessionFactoryProducer.java

@ApplicationScoped 
public class SessionFactoryProducer { 
    @ApplicationScoped 
    @Produces 
    @SessionFactoryProvider 
    public SqlSessionFactory produce() throws Exception { 
     SqlSessionFactory sessionFactory; 
     try (Reader reader = Resources.getResourceAsReader("mybatis.xml")) { 
      sessionFactory = new SqlSessionFactoryBuilder().build(reader); 
     } 
     // create sample table 
     //createTable(sessionFactory); 

     return sessionFactory; 
    } 

    private void createTable(final SqlSessionFactory manager) throws Exception { 
     try (SqlSession session = manager.openSession()) { 
      LOGGER.info("-> Initializing database..."); 
      Connection conn = session.getConnection(); 
      Reader reader = Resources.getResourceAsReader("create-table-postgresql.sql"); 
      ScriptRunner runner = new ScriptRunner(conn); 
      runner.runScript(reader); 
      reader.close(); 
      LOGGER.info("=> Database has been initialized properly."); 
     } catch (Exception ex) { 
      LOGGER.error("Error executing SQL Script...", ex); 
     } 
    } 
} 

Git项目被更新。

+0

如果您尝试在非测试环境中运行它,它会工作吗? – blackwizard

+0

是的,如果我将战争部署到payara服务器,它可以工作。 – zappee

回答

1

在这里和现在,我没有资源克隆和运行您的项目来确认我会说什么。但我会在星期一,如果有必要,在此期间,以下可能是一条轨道:

我认为这是行不通的,因为缺少一些非常重要的东西:SqlSessionFactory。在第一段

mybatis-cdi doc状态:

而SqlSessionFactory是任何的MyBatis豆的来源,以便首先你 需要创建一个(至少)而让容器知道它 存在。

事实上,如果没有Session,没有理由获得Mapper实例。如果@Mapper注释足够了,它只能提供一个空壳,因为没有链接到任何底层数据源。 然后如果没有映射器,它就不能被注入到EJB中,这就是Weld抱怨的事情。

部署成功时,是否与@Inject private AccountDao accountDao?我不明白为什么Weld会允许没有任何注射。但是如果是这样,请检查accountDao值(调试中断点或日志)。

+0

SQLSessionFactory从测试中丢失。万分感谢。 – zappee