1. 程式人生 > >Spring+SpringMVC+MyBatis+easyUI整合優化篇(四)單元測試例項

Spring+SpringMVC+MyBatis+easyUI整合優化篇(四)單元測試例項

日常囉嗦

前一篇文章《Spring+SpringMVC+MyBatis+easyUI整合優化篇(三)程式碼測試》講了不為和不能兩個狀態,針對不為,只能自己調整心態了,而對於不能,本文會結合一些例項進行講解,應該可以使得你掌握單元測試的方法。篇幅所限,所以先寫三個型別的測試例項,首先是自己平時寫著玩兒的測試類,然後分別是針對資料層和業務層的測試,程式碼都已經上傳到github上了。
我的github地址

簡單的測試

我們可能常常會碰到這種事情,需要實現一個功能的時候,忽然想不起來該用什麼方法了,或者忽然忘記一個方法該怎麼用了,這個時候我可能會查一下API然後寫一個簡單的測試方法,並沒有明確的要去測試什麼功能,只是簡單的驗證一個函式的用法,或者自己實在不確定一個方法該怎麼用了,用這種方式加深一下印象。

     // 得到MD5加密的內容
    @Test
    public void md5Test() {
        System.out.println(MD5Util.MD5Encode("ssm-maven-secret", "UTF-8"));
     //83d8d99f45f62461cc7b7ee76b448cb0
    }


     // 通過substring()獲取檔名
    @Test
    public void subStringTest() {
        //通過substring()獲取檔名
        String url = "https://s.doubanio.com/f/shire/5522dd1f5b742d1e1394a17f44d590646b63871d/pics/book-default-medium.gif"
; url = url.substring(url.lastIndexOf("/") + 1); System.out.println(url); //book-default-medium.gif }

這個只是自己的個人習慣,記憶力有時候真的差。

資料層單元測試

針對書籍模組的測試類,講解在程式碼中:

@RunWith(SpringJUnit4ClassRunner.class) //指定測試用例的執行器 這裡是指定了Junit4
@ContextConfiguration("classpath:applicationContext.xml"
)//裝配Spring public class BookDaoTest { //自動注入,需要將BookDao納入到Spring容器的管理下,不然會報錯 @Autowired private BookDao bookDao; @Test public void getBookByIdTest() { Book book1 = bookDao.getBookById("1"); Assert.assertEquals(book1, null);//判斷兩個引數是否相同,返回true的話則測試通過,不然控制檯會亮紅燈。 Book book2 = bookDao.getBookById("1002"); Assert.assertEquals(book2.getTitle(), "材料成型概論"); // Assert.assertEquals(book2.getTitle(), "我隨便寫一個"); //寫了三個斷言,可以分別進行測試,也可以根據上面三個斷言自己編寫測試。 } }

針對書籍模組的測試類,講解也都在程式碼中:


@RunWith(SpringJUnit4ClassRunner.class) //指定測試用例的執行器 這裡是指定了Junit4
@ContextConfiguration("classpath:applicationContext.xml")

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
//預設回滾,即此類中的方法即使執行成功,資料也並不會真正的修改,方法執行後會回滾。
//因為對資料庫的增刪改都會回滾,因此便於測試用例的迴圈利用
//前面書籍模組的測試由於只有查詢方法所以沒有加這個註解。
//如果想看到資料庫中的資料隨著測試而發生變化可以去掉這個註解。
public class UserDaoTest {
    @Autowired
    //自動注入,需要將BookDao納入到Spring容器的管理下
    private UserDao userDao;

    @Test
    public void loginTest() {
        User user = new User();
        user.setUserName("admin");
        user.setPassword("123456");
        //斷言此姓名和密碼的使用者為空
        //密碼並沒有加密,所以登入失敗,返回的使用者物件為空。
        Assert.assertEquals(userDao.login(user), null);
        User user2 = new User();
        user2.setUserName("admin");
        user2.setPassword(MD5Util.MD5Encode("123456", "UTF-8"));
        //斷言此姓名和密碼的使用者可以登入成功,且使用者id為2
        Assert.assertTrue(userDao.login(user2).getId() == 2);
        //執行下面這個斷言則會報錯。
        //Assert.assertTrue(userDao.login(user2).getId() == 3);

    }

    @Test
    public void findUsersTest() {
        //斷言此時返回的使用者列表數大於0
        Assert.assertTrue(userDao.findUsers(null).size() > 0);
        //斷言此時返回的使用者列表數等於3,數字你可以隨便寫,使用者數可能是錯的,如果報錯你會看到控制檯一片紅色
        Assert.assertTrue(userDao.findUsers(null).size() == 3);
    }

    @Test
    public void getTotalUserTest() {
        Assert.assertTrue(userDao.getTotalUser(null) > 0);
        Assert.assertTrue(userDao.getTotalUser(null) == 3);
    }

//使用update、insert、delete方法時,會得到一個返回值,這個返回值說明了執行一條sql語句後,表中有多少條記錄被影響了。
//比如用update修改一條記錄,如果修改成功了,返回值為1,返回0則是修改失敗。

    @Test
    public void updateUserTest() {
        User user = new User();
        user.setId(51);
        user.setPassword("1221");
        //大於0的意思是成功修改了一條記錄,即修改成功,如果updateUser()方法返回值等於0,即修改失敗
        Assert.assertTrue(userDao.updateUser(user) > 0);
        User user2 = new User();
        user2.setId(1000);
        user2.setPassword("234y9823y89hhao");
        Assert.assertTrue(userDao.updateUser(user2) > 0);
    }

    @Test
    public void addUserTest() {
        User user = new User();
        user.setUserName("測試使用者");
        user.setPassword(MD5Util.MD5Encode("testuser", "UTF-8"));
        //大於0的意思是影響了資料庫中的一條記錄,即新增成功
        Assert.assertTrue(userDao.addUser(user) > 0);
    }

    @Test
    public void deleteUserTest() {
        Assert.assertTrue(userDao.deleteUser(51) > 0);
    }

}

大家可以將程式碼pull到本地進行測試,並根據上面幾個方法寫一下自己的測試用例。

service的單元測試

其實service層的單元測試和dao層並沒有太多區別,唯一的不同可能就是service層方法中可以執行多條sql語句,而dao層的方法只能執行一條sql語句,因此這個例子更側重於講一下事務問題

配置檔案:

    <!-- 配置事務通知屬性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 定義事務傳播屬性 -->
        <tx:attributes>
        <!--事務切面中insert開頭的方法會被納入事務管理中-->
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="upd*" propagation="REQUIRED"/>
        </tx:attributes>
        ......
    </tx:advice>

    <!-- 配置事務切面 -->
    <aop:config>
        <aop:pointcut id="serviceOperation"
                      expression="(execution(* com.ssm.maven.core.service.*.*(..)))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
    </aop:config>

業務方法:

//通過Spring的配置檔案,此方法已經納入到其事務管理下
//發生異常時會觸發事務回滾,資料不會被更改
public int insertStore(Store store) {
        int level = Integer.valueOf(store.getLevel());
        for (int i = 1; i < level; i++) {
            store.setLevel(i + "");
            storeDao.insertStore(store);
        }
        store.setLevel(level + "");
        int result = storeDao.insertStore(store);
        int i = 10 / 0;
        //發生異常,操作回滾.
        //可以試著將上面一條語句註釋掉再執行測試用例,看看有什麼區別。
        return result;
    }

測試用例:

@RunWith(SpringJUnit4ClassRunner.class) //指定測試用例的執行器 這裡是指定了Junit4
@ContextConfiguration("classpath:applicationContext.xml")
//@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
//不新增此設定,測試service層的事務管理
//service層與dao層的測試時相同的,不同之處,在於service層多數都會在配置檔案中配置spring的事務管理
public class StoreServiceTest {
    @Autowired
    private StoreService storeService;

    @Test
    public void insertStoreTest() {
        Store store = new Store();
        store.setLevel("5");
        store.setNumber("TEST");
        storeService.insertStore(store);
        int i = 10 / 0;
        //這裡發生異常是不會回滾的,因為此方法並沒有被納入事務管理中
    }

}

這個例子可能有些簡單,一般業務層方法都會較為複雜,如下:

function(){
-A-

SQL1

-B-

SQL2

-C-

SQL3

-D-
}

那麼執行此方法時,無論在A處、B處、C處、D處發生異常,都會觸發事務回滾,關於Spring的事務管理事務傳播屬性,想了解的可以自己去查詢一下。

總結

本篇主要講了資料層和業務層的測試,下一篇主要會講一下controller控制層的測試,睡覺啦…