编写测试单元遇到的问题

public class TestDaoCase extends AbstractTransactionalDataSourceSpringContextTests {
    @Override
    protected String[] getConfigLocations() {
        return new String[] { "file:F:\\shenghuoNet\\WebRoot\\WEB-INF\\applicationContext.xml"};
    }
    
    public TestDaoCase(){
        super();
        setAutowireMode(AUTOWIRE_BY_NAME);
        setDefaultRollback(true);
        this.setDependencyCheck(false);
        setPopulateProtectedVariables(true);
        jdbcTemplate=new JdbcTemplate((DataSource)getContext(getConfigLocations()).getBean("dataSource"));
        
    }
    
    private ApplicationContext applicationContext;

   

    public ApplicationContext getContext(String[] filePath)
    {
      return new ClassPathXmlApplicationContext(filePath);
    }
    public void testConfig() {       
        assertNotNull("spring-mock context has bean init()",this.getConfigLocations());
    }

    public static void main(String[] args)
    {
      TestRunner.run(TestDaoCase.class);
    } 
    public void testFindById() {
        ShnMember shnMember = new ShnMember();
//      shnMember.setPasswd("darksun");
//      shnMember.setCreatetime(new Date());
//      shnMember.setUsername("darksun");
        ITestService is=(ITestService)getContext(getConfigLocations()).getBean("TestDAO");
        
        try {
            shnMember=is.findById(1l);
        } catch (Exception e) {
            fail(e.getMessage());
        }
//        String name = (String) jdbcTemplate.queryForObject("select username from shn_member where memberid=?", new Object[]{shnMember.getMemberid()}, Long.class);
       
        assertEquals(shnMember.getUsername(), "shenghuo");
    } 
    
    public void testSave() {
        ShnMember shnMember = new ShnMember();
        shnMember.setPasswd("darksun");
        shnMember.setCreatetime(new Date());
        shnMember.setUsername("xingfu pig");
        ShnRole role=new ShnRole();
        role.setRoleid(1l);
        shnMember.setShnRole(role);
        ITestService is=(ITestService)getContext(getConfigLocations()).getBean("TestDAO");
        
        try {
            is.save(shnMember);
        } catch (Exception e) {
            fail(e.getMessage());
        }
        
        String name = (String) jdbcTemplate.queryForObject("select username from shn_member where memberid=?", new Object[]{shnMember.getMemberid()}, Long.class);
       
        assertEquals(shnMember.getUsername(), name);
    } 

}


以上是我的测试代码

There was 1 error:
1) testSave(TestUnit.TestDaoCase)org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
at org.springframework.dao.support.DataAccessUtils.requiredSingleResult(DataAccessUtils.java:71)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:679)
at TestUnit.TestDaoCase.testSave(TestDaoCase.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
at TestUnit.TestDaoCase.main(TestDaoCase.java:50)
这个是错误提示

问题我也知道了 就是因为没提交 所以jdbc怎么也找不到数据 但问题是我不希望测试数据插进数据库 有什么方法能解决

 


问题补充:
to:小疯子
1. 我是没办法 因为如果不写 jdbcTemplate为空 我不知道是什么原因

2. 那个是不自然 因为刚写的时候 怎么都读不到 改了几次 后来配好没有改 - -!

3.问题就是这个了 没有提交 jdbc就找不到数据 要找数据就要提交 所以才找人问
问题补充:
 
public class TestDao2Case extends
        AbstractTransactionalDataSourceSpringContextTests {
    @Override
    protected String[] getConfigLocations() {
        return new String[] { "file:F:\\shenghuoNet\\WebRoot\\WEB-INF\\applicationContext.xml" };
    }

    ITestService testDao; // 自己会注入的.

    // 需要写setter方法.
    public void setTestDAO(ITestService testService) {
        this.testDao = testService;
    }


    public void testSave() {
        ShnMember shnMember = new ShnMember();
        shnMember.setPasswd("darksun");
        shnMember.setCreatetime(new Date());
        shnMember.setUsername("xingfus 54zhf1tou");
        ShnRole role = new ShnRole();
        role.setRoleid(1l);
        shnMember.setShnRole(role);

        try {
            testDao.save(shnMember);

        } catch (Exception e) {
            fail(e.getMessage());
        }

        String name = (String) jdbcTemplate.queryForObject(
                "select username from shn_member where memberid=?",
                new Object[] { shnMember.getMemberid() }, String.class);

        assertEquals(shnMember.getUsername(), name);
    }


    public void testFindById() {
        ShnMember shnMember = new ShnMember();


        try {
            shnMember = testDao.findById(1l);
        } catch (Exception e) {
            fail(e.getMessage());
        }
        assertEquals(shnMember.getUsername(), "shenghuo");
    }
    
    public static void main(String[] args) {
        TestRunner.run(TestDao2Case.class);
    }
}




这个是修改过的



错误提示:

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

at org.springframework.dao.support.DataAccessUtils.requiredSingleResult(DataAccessUtils.java:71)

at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:669)

at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:679)

at TestUnit.TestDao2Case.testSave(TestDao2Case.java:44)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at junit.framework.TestCase.runTest(TestCase.java:168)

at junit.framework.TestCase.runBare(TestCase.java:134)

at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)

at junit.framework.TestResult$1.protect(TestResult.java:110)

at junit.framework.TestResult.runProtected(TestResult.java:128)

at junit.framework.TestResult.run(TestResult.java:113)

at junit.framework.TestCase.run(TestCase.java:124)

at junit.framework.TestSuite.runTest(TestSuite.java:232)

at junit.framework.TestSuite.run(TestSuite.java:227)

at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:76)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)




问题补充:
恩 谢谢两位大大 就是最后一个问题解决不了



就是这个问题

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0



jdbc找不到未提交的数据
问题补充:
to:logger

很感谢大哥这么热心 可是问题不是异常 出异常的原因是因为我在测试保存数据

数据保存了 但是没提交 然后用jdbc去查询 希望获得这条数据 来确认保存成功

恩 结果就出现这个异常了 如果我提交了 那么数据就插进数据库了 同时测试也能通过

我试验过了 我希望测试的时候不会插脏数据进数据库 可是如果不提交 就会出现这个异常



恩 再次感谢一下大大
问题补充:
恩 谢谢两位大大 问题我已经解决了

首先 是applicationContext.xml 哪里要配置事务管理 我配置的时候少了save的方法 所以没有管理到 呵呵

第二是要getHiberateTemplate().flush 要不然 也出同样的错误

很感谢两位

[code="java"] public Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException {
List results = query(sql, rowMapper);
return DataAccessUtils.requiredSingleResult(results);
}[/code]

[code="java"] public static Object requiredSingleResult(Collection results) throws IncorrectResultSizeDataAccessException {
int size = (results != null ? results.size() : 0);
if (size == 0) {
throw new EmptyResultDataAccessException(1);
}
if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, size);
}
return results.iterator().next();
}[/code]

1, AbstractTransactionalDataSourceSpringContextTests本身就提供了JdbcTemplate的支持, 你的这种写法好像是多余的吧:[code="java"]jdbcTemplate=new JdbcTemplate((DataSource)getContext(getConfigLocations()).getBean("dataSource")); [/code]
2, 在这段代码中:
[code="java"]ITestService is=(ITestService)getContext(getConfigLocations()).getBean("TestDAO"); [/code], 你用这种方式去拿ITestService的实例好像也不自然吧!你只要在你的TestDaoCase中提供ITestService的成员变量, 然后给它一个setter方法,AbstractTransactionalDataSourceSpringContextTests会自动帮你注入进来的啊![code="java"] private ITestService is;

public void setIs(ITestService is){
    this.is = is;
}[/code]

3,在AbstractTransactionalDataSourceSpringContextTests的每个test方法中, 就算你将测试数据插进数据库,在最后都会rollback的啊, 所以你不用担心会污染你的数据,除非你主动调用setComplete()将数据插入数据库, 不然都会 rollback 。

修正一下的代码:
[code="java"]public class TestDaoCase extends AbstractTransactionalDataSourceSpringContextTests {

@Override

protected String[] getConfigLocations() {

return new String[] { "file:F:\shenghuoNet\WebRoot\WEB-INF\applicationContext.xml"};

}

ITestService testService; // 自己会注入的.

// 需要写setter方法.
public void setTestService(ITestService testService) {
this.testService = testService;
}

//jdbcTemplate=new JdbcTemplate((DataSource)getContext(getConfigLocations()).getBean("dataSource"));
// 去掉, jdbcTemplate可以直接用的. 不用再初始化.
...
}[/code]

AbstractTransactionalDataSourceSpringContextTests 是会在每个test方法结束后回滚的. 不会将数据插入到数据库的.

[code="java"] @Override
protected void onSetUpInTransaction() throws Exception {
// TODO Auto-generated method stub
super.onSetUpInTransaction();
}[/code]

你可以将每次都需要的数据放到这个里面去. 让这个方法去插入数据. 也就是每个test执行前都会重新插入一个数据, 因为前面一个test结束了, 测试数据也回滚掉了. 要重新做数据.

哈哈, 我直接用DBUnit初始化数据!

[code="java"] public TestDaoCase(){

super();

setAutowireMode(AUTOWIRE_BY_NAME);

setDefaultRollback(true);

this.setDependencyCheck(false);

setPopulateProtectedVariables(true);

jdbcTemplate=new JdbcTemplate((DataSource)getContext(getConfigLocations()).getBean("dataSource"));

}  [/code]

你可以尝试先将这个方法注掉.

用query, 不用queryForObject, 因为结果是空, 会抛异常的.

刚看完李宁点火, 接着给你回答问题!哈哈!
我把你的案例在我的本机上测试了一下, 写法上是完全没有问题的!不过我不知道你的shnMember.getMemberid()里面的memberid是什么东西, 是主键吗?自增的吗?你最好把shnMember.getMemberid()打出来看一下, 看是不是为null!如果是null我也会抛和你一样的错误!
[code="java"]
Sysout.out.println(shnMember.getMemberid());
assertNotNull(shnMember.getMemberid());
[/code]加在
[code="java"] String name = (String) jdbcTemplate.queryForObject(

"select username from shn_member where memberid=?",

new Object[] { shnMember.getMemberid() }, String.class); [/code]这段代码的前面.