亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

學習TDD(2)--實例:ProtoStuffUtil類的測試

2019-11-11 05:11:03
字體:
來源:轉載
供稿:網友

上篇講了TDD的步驟和各種好處,俗話說的好,站在岸上是學不會游泳的。所以我們還是要拿個例子出來,實踐一下TDD。

因為是第一次嘗試,我想還是選個簡單的例子,之前寫的那個PRotoStuffUtil類就很不錯。這個類主要負責對象跟byte[]之間的相互轉換。可以參考http://blog.csdn.net/mrbcy/article/details/54869113。其實這個類已經寫好了,不太符合TDD的規范。但是體驗一下還是可以的。

配套的代碼已經上傳到http://download.csdn.net/detail/mrbcy/9748501

這個類雖然簡單但是測試的流程還是很曲折

測試目標

因為這個類是負責對象跟byte[]之間的相互轉換,所以我想從兩個方面測試它:

第一個是能夠對復雜的對象進行正確的編碼解碼第二個是對復雜對象構成的List、Map進行正確的編碼解碼

測試代碼

來看對象類代碼

package tech.mrbcy.mrpc.test.domain;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.List;import java.util.Map;import com.sun.org.apache.bcel.internal.generic.NEW;import tech.mrbcy.mrpc.test.enumm.UserType;public class User { private int userId; private String userName; private boolean lockState; private UserType userType; private List<String> addresses = new ArrayList<String>(); private Map<String, String> favoriteMap = new HashMap<String, String>(); // getters and setters public void addAddress(String address){ addresses.add(address); } public void putFavor(String key,String value){ favoriteMap.put(key, value); } @Override public String toString() { return "User [userId=" + userId + ", userName=" + userName + ", lockState=" + lockState + ", userType=" + userType + ", addresses=" + addresses + ", favoriteMap=" + favoriteMap + "]"; }}

看起來對象很復雜了,各種的數據類型和list map也都用上去了。接下來我們編寫第一個測試??创a。

@Test// 對復雜對象進行解碼編碼public void testObject(){ User user = new User(); user.setUserId(10086); user.setUserName("張三"); user.setLockState(true); user.setUserType(UserType.Vip_USER); user.addAddress("上海"); user.addAddress("北京"); user.putFavor("tdd", "當當網"); user.putFavor("java","Amazon"); // 保存轉換之前的toString結果 String oldString = user.toString(); // 轉換 byte[] data = ProtostuffUtil.serializer(user); User newUser = ProtostuffUtil.deserializer(data, User.class); // 保存轉換之后的toString結果 String newString = newUser.toString(); assertEquals(oldString,newString);}

執行結果是通過。

然后編寫第二個測試。

@Test// 對復雜對象的列表進行編碼解碼public void testList(){ List<User> users = new ArrayList<User>(); User user = new User(); user.setUserId(10086); user.setUserName("張三"); user.setLockState(true); user.setUserType(UserType.VIP_USER); user.addAddress("上海"); user.addAddress("北京"); user.putFavor("tdd", "當當網"); user.putFavor("java","Amazon"); users.add(user); User user2 = new User(); user2.setUserId(10086); user2.setUserName("張三"); user2.setLockState(true); user2.setUserType(UserType.VIP_USER); user2.addAddress("上海"); user2.addAddress("北京"); user2.putFavor("tdd", "當當網"); user2.putFavor("java","Amazon"); users.add(user); // 保存轉換之前的toString結果 String oldString = users.toString(); // 轉換 byte[] data = ProtostuffUtil.serializer(users); List<User> newUsers = ProtostuffUtil.deserializer(data, users.getClass()); // 保存轉換之后的toString結果 for(User u : newUsers){ System.out.println(u); } String newString = newUsers.toString(); assertEquals(oldString,newString);}

看到重復代碼出現了,暫時不管它,重要的是先讓測試通過。但是,執行結果是失敗。

報出的錯誤是并發操作List時常出現的錯誤,就是通過外部強行修改了List的內部狀態導致的。

我非常的不解,難道對象的List不能和byte[]相互轉換?把List包到對象里面試試看。

@Test// 把List包到對象里進行編碼解碼public void testUserPack(){ List<User> users = new ArrayList<User>(); User user = new User(); user.setUserId(10086); user.setUserName("張三"); user.setLockState(true); user.setUserType(UserType.VIP_USER); user.addAddress("上海"); user.addAddress("北京"); user.putFavor("tdd", "當當網"); user.putFavor("java","Amazon"); users.add(user); User user2 = new User(); user2.setUserId(10086); user2.setUserName("張三"); user2.setLockState(true); user2.setUserType(UserType.VIP_USER); user2.addAddress("上海"); user2.addAddress("北京"); user2.putFavor("tdd", "當當網"); user2.putFavor("java","Amazon"); users.add(user); UserListPack ulp = new UserListPack(); ulp.setUsers(users); // 保存轉換之前的toString結果 String oldString = ulp.toString(); // 轉換 byte[] data = ProtostuffUtil.serializer(ulp); UserListPack newUlp = ProtostuffUtil.deserializer(data, UserListPack.class); // 保存轉換之后的toString結果 String newString = newUlp.toString(); assertEquals(oldString,newString);}

UserListPack.java

public class UserListPack { List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } @Override public String toString() { return "UserListPack [users=" + users + "]"; }}

執行的結果是成功。難道ProtoStuff不能轉換List Map這樣的數據?于是我又寫了一個Map的測試。

@Testpublic void testMap(){ Map<Integer, User> uMap = new HashMap<Integer, User>(); User user = new User(); user.setUserId(10086); user.setUserName("張三"); user.setLockState(true); user.setUserType(UserType.VIP_USER); user.addAddress("上海"); user.addAddress("北京"); user.putFavor("tdd", "當當網"); user.putFavor("java","Amazon"); uMap.put(1,user); User user2 = new User(); user2.setUserId(10086); user2.setUserName("張三"); user2.setLockState(true); user2.setUserType(UserType.VIP_USER); user2.addAddress("上海"); user2.addAddress("北京"); user2.putFavor("tdd", "當當網"); user2.putFavor("java","Amazon"); uMap.put(2,user); // 保存轉換之前的toString結果 String oldString = uMap.toString(); // 轉換 byte[] data = ProtostuffUtil.serializer(uMap); Map<Integer, User> newMap = ProtostuffUtil.deserializer(data, uMap.getClass()); // 保存轉換之后的toString結果 String newString = newMap.toString(); assertEquals(oldString,newString);}

結果失敗了。

注意畫紅框的那里,說明轉換出來的Map是空的??磥鞵rotoStuff真的不能從byte[]轉List Map了。

我又去搜了一下Java byte[] to List也沒有好的解決辦法。

——更新:Google找到了————————–

ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));try { @SuppressWarnings("unchecked") ArrayList<Object> list = (ArrayList<Object>) ois.readObject(); ...} finally { ois.close();}

對應的List to byte[]代碼是:

ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = null;oos = new ObjectOutputStream(bos);oos.writeObject(mArrayList);//mArrayList is the array to convertbyte[] buff = bos.toByteArray();

這個代碼我還沒試。后續看看要不要干脆拋棄ProtoStuff,用上面的方法進行Object和byte[]互轉算了。

————————————————-

事到如今我知道ProtoStuffUtil只能轉Object,所以只能先修改測試的代碼,允許它拋異常,讓測試先過掉了。

testMap的最后一句斷言修改為assertEquals("{}",newString);

testList的@Test注解修改為@Test(expected = ConcurrentModificationException.class)

這樣測試就都通過了。

測試重構

這4個測試中的重復代碼主要集中在User對象的創建及屬性賦值和轉換并比較前后字符串這兩部分。

創建User的函數,只修改id和userName就足夠了。

private User createUser(Integer userId, String userName){ User user = new User(); user.setUserId(userId); user.setUserName(userName); user.setLockState(true); user.setUserType(UserType.VIP_USER); user.addAddress("上海"); user.addAddress("北京"); user.putFavor("tdd", "當當網"); user.putFavor("java","Amazon"); return user;}

執行比較的函數

private void doCompare(Object oldObj){ // 保存轉換之前的toString結果 String oldString = oldObj.toString(); doCompare(oldObj, oldString);}private void doCompare(Object oldObj,String expectStr){ // 轉換 byte[] data = ProtostuffUtil.serializer(oldObj); Object newObj = ProtostuffUtil.deserializer(data, oldObj.getClass()); // 保存轉換之后的toString結果 String newString = newObj.toString(); assertEquals(expectStr,newString);}

重構以后的測試代碼變得非常精簡。

@Test// 對復雜對象進行解碼編碼public void testObject(){ User user = createUser(10086, "張三"); doCompare(user);}

重構后4個測試依然是通過的。

總結

初步嘗試了TDD的流程,雖然沒有走的很完整,但是也體驗到了單元測試的好處。經過單元測試的類感覺能放心用了。為了避免盲目的信心,以后還要學習測試的相關理論,編寫出更合理的測試用例。

下一次要實現某個類的時候再寫一次TDD初探,體驗完整的流程。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久噜噜噜精品国产亚洲综合| 日韩在线观看网址| 一本色道久久综合狠狠躁篇怎么玩| 色偷偷偷亚洲综合网另类| 九九精品视频在线| 国产免费一区二区三区在线观看| 亚洲欧美综合图区| 国产精品视频大全| 黄网动漫久久久| 欧美大片免费观看| 国产一区私人高清影院| 久久精品欧美视频| 国产精品毛片a∨一区二区三区|国| 欧美性黄网官网| 欧美在线观看www| 久久精品久久久久电影| 亚洲日本欧美中文幕| 91高潮精品免费porn| 78m国产成人精品视频| 久久好看免费视频| xvideos成人免费中文版| 亚洲a成v人在线观看| 亚洲欧美综合另类中字| 国产精品青青在线观看爽香蕉| 欧美日韩国产丝袜美女| 亚洲va电影大全| 8090理伦午夜在线电影| 成人激情免费在线| 一道本无吗dⅴd在线播放一区| 这里只有精品丝袜| 日韩亚洲成人av在线| 久久精品视频亚洲| 亚洲欧洲美洲在线综合| 2019国产精品自在线拍国产不卡| 夜夜嗨av色一区二区不卡| 久久这里只有精品99| 国产精品入口尤物| 国产日产欧美a一级在线| 午夜精品久久久久久久男人的天堂| 国产区亚洲区欧美区| 91免费精品视频| 欧美日韩国产黄| 国产丝袜一区二区三区免费视频| 国产精品极品美女在线观看免费| 亚洲国产女人aaa毛片在线| 57pao国产成人免费| 在线播放精品一区二区三区| 亚洲国产精品久久久久秋霞不卡| 亚洲石原莉奈一区二区在线观看| yw.139尤物在线精品视频| 欧美日韩亚洲精品一区二区三区| 性欧美xxxx视频在线观看| 日韩动漫免费观看电视剧高清| 午夜精品久久久久久99热| 青草热久免费精品视频| 姬川优奈aav一区二区| 国产亚洲免费的视频看| 久久久久国产一区二区三区| 欧美成人午夜视频| 456国产精品| 亚洲男子天堂网| 日韩精品在线观看一区二区| 国产色视频一区| 福利视频导航一区| 国产成人啪精品视频免费网| 国产精品99久久久久久久久久久久| 久久久久久久一| 日韩精品视频在线播放| 91精品国产一区| 国产日韩精品综合网站| 亚洲精品国产suv| 国产精品久久久久7777婷婷| 在线播放精品一区二区三区| 91免费视频网站| 国产精品成人播放| 国产亚洲欧洲黄色| 亚洲天堂av图片| 亚洲国产精品久久久久秋霞不卡| 欧美日韩国产一区在线| 美女福利视频一区| 国产在线视频欧美| 91国偷自产一区二区三区的观看方式| 92版电视剧仙鹤神针在线观看| 欧美性猛交xxx| 久久夜色精品国产欧美乱| 日本一区二区在线免费播放| 丰满岳妇乱一区二区三区| 国产精品高潮粉嫩av| www欧美xxxx| 日本精品久久中文字幕佐佐木| 欧美日韩另类视频| 少妇高潮久久77777| 日本午夜在线亚洲.国产| 日韩电影大全免费观看2023年上| 亚洲人成在线播放| 久久久久北条麻妃免费看| 国产精品美女主播| 国产亚洲精品久久久久久牛牛| 2019中文字幕全在线观看| 亚洲欧洲xxxx| 91精品啪aⅴ在线观看国产| 欧美性猛交丰臀xxxxx网站| 韩国美女主播一区| 亚洲最大福利视频网站| 91精品在线播放| 久热精品视频在线观看| 精品欧美激情精品一区| 欧美国产日韩一区| 亚洲国产精久久久久久久| 欧美日韩一区二区三区在线免费观看| 欧美日韩国产一区在线| 懂色av一区二区三区| 青青草精品毛片| 亚洲在线观看视频网站| 精品亚洲一区二区三区在线播放| 亚洲免费av网址| 久久亚洲综合国产精品99麻豆精品福利| 色噜噜狠狠色综合网图区| 欧美日韩国产在线| 亚洲3p在线观看| 欧美最猛性xxxxx免费| 欧美床上激情在线观看| 91av中文字幕| 亚洲成人1234| 亚洲乱码国产乱码精品精| 欧美日韩一区二区免费视频| 亚洲欧洲在线免费| 亚洲片在线观看| 国产成人激情视频| 日日骚久久av| 日韩欧美综合在线视频| 午夜精品一区二区三区在线播放| 国产精品一二三视频| 亚洲欧美中文字幕在线一区| 狠狠躁夜夜躁人人爽天天天天97| 日韩影视在线观看| 久久久精品久久久| 国产精品av在线播放| 日本一区二区在线播放| 欧美激情国产精品| 98精品国产高清在线xxxx天堂| 日韩av影视综合网| 欧美性猛交xxxx乱大交3| 久久精品成人欧美大片古装| 久久夜色精品国产欧美乱| 中文字幕日韩在线视频| 久久国产精品影视| 国自产精品手机在线观看视频| 欧美极度另类性三渗透| 人九九综合九九宗合| 欧美日韩国产限制| 日韩欧美在线第一页| 日韩欧美有码在线| 91美女片黄在线观看游戏| 亚洲人成伊人成综合网久久久| 亚洲性夜色噜噜噜7777| 午夜免费日韩视频| 亚洲午夜色婷婷在线| 国产91精品视频在线观看| 欧美亚洲另类视频| 亚洲免费精彩视频| 国产欧美一区二区三区在线看| 日韩av网址在线观看| 久久综合电影一区|