如何使用Arquillian(PART2)模拟MyBatis映射器接口?

时间:2017-03-10 21:38:16

标签: java junit mocking mybatis jboss-arquillian

这是我第二次尝试使用MyBatis创建集成测试。我尝试了很多东西,但似乎没有解决这个问题的方法。希望你们能帮助我。

In my previous question我尝试编写集成测试来检查我的其余API的输出。方案如下:rest API调用一个注入的EJB,它使用MyBatis执行一些SQL:rest api> ejb> MyBatis的。不幸的是我既不能注射也不能模拟MyBatis映射器界面,所以我的测试不起作用:(

现在我创建了另一个测试场景,但最终我遇到了同样的情况。 现在我的场景非常简单:我有一个带有MyBatis映射器的EJB。我想在带有Arquillian的嵌入式Glassfish / Payara服务器中测试它。

这是我的例外:

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";
    }
}

帐户专家(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中的两行以删除对MyBatis映射器的依赖,那么我的测试工作正常。

I uploaded the source code to github as well.

我的测试中缺少以下课程。 @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项目已更新。

1 个答案:

答案 0 :(得分:1)

此时此刻,我没有资源来克隆和运行您的项目以确认我要说的内容。但是如果有必要,我会在星期一,同时,以下内容可能是一条轨道:

我认为它不起作用,因为缺少一些非常重要的东西:SqlSessionFactory

第一段中的

mybatis-cdi doc个州:

  

SqlSessionFactory是任何MyBatis bean的源代码,所以首先是你   需要创建一个(至少)并让容器知道它   存在。

实际上,如果没有Session,没有理由获得Mapper实例。如果@Mapper注释足够,它只能提供一个空shell,因为它没有链接到任何基础数据源。 然后,如果没有Mapper,它就不能被注入到EJB中,这就是Weld所抱怨的。

部署成功时,是否为@Inject private AccountDao accountDao?我不明白为什么韦尔德会允许注射什么。但如果是,请检查accountDao值(调试断点或日志)。