如何模拟MyBatis映射器接口?

时间:2017-03-03 15:30:55

标签: java junit jersey mockito mybatis

我正在为我的Jersey rest API编写单元测试,该API在后台使用MyBatis。

这是我班级的结构:

休息服务:

@Path("/api")
public class HelloRestService {
    @Inject
    HelloBean helloBean;

    @GET
    @Path("/echo/{name}")
    public Response echo(@PathParam("name") String name) {
        return Response.status(200).entity(helloBean.sayHello(name)).build();
    }
}

无状态EJB:

@Stateless
public class HelloStatelessBean implements HelloBean {
    // Injected MyBatis mapper (dao)
    @Inject
    private EmployeeMapper employeeMapper;

    @Override
    public Employee getEmployeeById(final Long id) {
        return employeeMapper.getEmployeeById(id);
    }

    @Override
    public ArrayList<Employee> getEmployee() {
        return employeeMapper.getAllEmployee();
    }

    /**
     * Echo.
     */
    @Override
    public String sayHello(String name) {
        return String.format("Hello %s! This is Ejb :)", name);
    }
}

MyBatis mapper界面:

@Dependent
@Mapper
public interface EmployeeMapper {
    @Select("select * from EMPLOYEE where id = #{id}")
    Employee getEmployeeById(Long id);

    @Select("select * from EMPLOYEE")
    ArrayList<Employee> getAllEmployee();
}

我有一个很好的junit测试来测试我的MyBatis映射器。它工作正常。下一步是我想为我的球衣休息班写一个测试。这就是我所拥有的:

public class HelloRestServiceTest extends JerseyTest {
    @Override
    public Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);

        return new ResourceConfig(HelloRestService.class) {
            {
                register(new HelloStatelessBean());
                register(Mockito.mock(EmployeeMapper.class));
            }
        };
    }

    @Test
    public void echo() throws Exception {
        Response response = target("/api/echo/John").request().get();
        Assert.assertEquals(200, response.getStatus());
        Assert.assertNotNull(response.getEntity());
    }
}

但是这个测试引发了一个例外:

org.glassfish.jersey.internal.inject.Providers checkProviderRuntime
WARNING: A provider a.b.HelloStatelessBean registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider a.b.HelloStatelessBean will be ignored. 
org.glassfish.jersey.internal.inject.Providers checkProviderRuntime
WARNING: A provider a.b.EmployeeMapper$$EnhancerByMockitoWithCGLIB$$ee86c913 registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider a.b.EmployeeMapper$$EnhancerByMockitoWithCGLIB$$ee86c913 will be ignored.
A MultiException has 1 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=EmployeeMapper,parent=HelloStatelessBean,qualifiers={},position=-1,optional=false,self=false,unqualified=null,52451302)
MultiException stack 1 of 1
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=EmployeeMapper,parent=HelloStatelessBean,qualifiers={},position=-1,optional=false,self=false,unqualified=null,52451302)

使用mockito模拟MyBatis映射器的正确方法是什么?

更新1 EJB测试就像魅力一样:

@RunWith(MockitoJUnitRunner.class)
public class HelloStatelessBeanTest {

    private static SqlSessionFactory sqlSessionFactory;

    @Spy
    private HelloBean helloBean = new HelloStatelessBean();

    @Test
    public void sayHello() throws Exception {

        String actual = helloBean.sayHello("Pear");
        System.out.println(actual);
    }

    @Test
    public void testGetEmployeeById() {
        // create an SqlSessionFactory
        try (Reader reader = Resources.getResourceAsReader("mybatis-configuration.xml")) {

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
            Employee employee = mapper.getEmployeeById(1l);
            Assert.assertNotNull(employee);
            Assert.assertNotNull(employee.getId());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

但它不适用于球衣。我已经尝试过这种方式了,但之前我得到了相同的例外:

public class HelloRestServiceTest extends JerseyTest {
    @Override
    public Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);

        return new ResourceConfig(HelloRestService.class) {
            {
                 try (Reader reader = Resources.getResourceAsReader("configuration.xml")) {
                     SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                     SqlSession sqlSession = sqlSessionFactory.openSession();
                     EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

                     register(new HelloStatelessBean());
                     register(mapper, EmployeeMapper.class);
                 } catch (Exception e) {
                     throw new RuntimeException(e);
                 }
            }
        };
    }

    @Test
    public void echo() throws Exception {
        Response response = target("/api/echo/Arnold").request().get();
        Assert.assertEquals(200, response.getStatus());
        Assert.assertNotNull(response.getEntity());
    }
}

有什么想法吗?

0 个答案:

没有答案