/**
 *  [Sample.java]
 *
 * 身份证旧号码转新号码 IdLiveUp.java 类的测试
 *
 *    测试用号码       应得到的校验码
 * 33028319830119003 4
 * 33010219820612001 8
 * 33028219820807001 5
 * 33020619821022307 x
 * 34052419800101001 x
 */public class Sample {
    public static void main(String args[]) {
     System.out.println("■■测试开始■■\n");
    
     System.out.println("[15、17位自适应]");
        new IdLiveUp("330283830119003");
        new IdLiveUp("33028319830119003");
        
        System.out.println("\n[出生日期的合法性校验]");
        new IdLiveUp("33028317830119003");
        new IdLiveUp("33028319830019003");
        new IdLiveUp("33028319830135003");
        
        System.out.println("\n[检验新号码\"校验码\"的正确性]");
        new IdLiveUp("330283198301190034");
        new IdLiveUp("33028319830119003x");
    }
}

解决方案 »

  1.   

    to:xiaohaiz(xiaohaiz) 我还是个新手,这个类也只是示范我不太明白“自动测试”,谢谢指教
      

  2.   

    to onefox(一品狐):
    比如说写程序最关心的是什么?首先是正确性(Correctness)和强壮性(Robustness).
    那通常靠什么来给你验证代码实现的正确和强壮呢?靠测试.
    现在回头看你的实现代码和给我们大家提供的测试代码IdLiveUp.java和Sample.java,这里我们先不讨论实现得如何,你的测试是如何保证呢?你必须运行Sample.java,然后靠System.out.println在终端上检查你的代码实现是否正确. 这当然也是测试,但是呢,明显不够成熟,因为还是靠你看和检查!
    那么,我们为什么不把这些计算机能够为我们测试的内容让程序自动为我们检查呢?
    所以这就把测试的重要度提到了前面.(如果再讨论测试驱动开发就跑题了 :) )
    为了测试,驱使你必须对你的结构进行重构,因为你现在的结构都在构造方法中实现所有的内容,没有为测试留出接口.为了保证测试的重构会使你的代码结构更为合理.(先写这些吧,一会为你尝试一下你的程序测试的实例)
      

  3.   

    btw, 你的代码有很好的文档注释习惯,一定要保持,特别是需要published的方法都需要文档注释.
      

  4.   

    先完成了一个自动测试的单元测试样例,只测试了旧转新的功能.
    public class TestIdLiveUp extends TestCase {
        public TestIdLiveUp(String name) {super(name);}    public void testConvertOldIdNumber() {
            String id = null;
            id = IdLiveUp.convertID(null);
            assertNull(id);                                 // Cannot covert null id
            id = IdLiveUp.convertID("foo");
            assertNull(id);                                 // Invalid id
            id = IdLiveUp.convertID("fffffffffffffff");
            assertNull(id);                                 // Invalid id (15 bits)
            id = IdLiveUp.convertID("fffffffffffffffff");
            assertNull(id);                                 // Invalid id (17 bits)
            id = IdLiveUp.convertID("123");
            assertNull(id);                                 // Invalid id
            id = IdLiveUp.convertID("33028317830119003");
            assertNull(id);                                 // Invalid year
            id = IdLiveUp.convertID("33028319830019003");
            assertNull(id);                                 // Invalid month
            id = IdLiveUp.convertID("33028319830135003");
            assertNull(id);                                 // Invalid day        id = IdLiveUp.convertID("330283830119003");
            assertNotNull(id);
            assertEquals(18, id.length());
            assertEquals("330283198301190034", id);
            id = IdLiveUp.convertID("33028319830119003");
            assertNotNull(id);
            assertEquals(18, id.length());
            assertEquals("330283198301190034", id);
        }    public void testCheckNewIdNumber() {    }
    }
    重构了你原有的IdLiveUp,只实现了转换的功能,算法是直接copy-paste的.
    当然,这只是初步的重构,目的就是为了演示单元测试.
    public final class IdLiveUp {
        public static final int OLD_15_BITS_ID_LEN = 15;
        public static final int OLD_17_BITS_ID_LEN = 17;    private IdLiveUp() {}    public static String convertID(String oldNum) {
            if(!validateIDForConvert(oldNum)) {return null;}
            String idForConvert = (oldNum.length()==OLD_15_BITS_ID_LEN)?(new StringBuffer(oldNum).insert(6,"19").toString()):oldNum;
            try{return convert(idForConvert);}
            catch(Exception ex){return null;}
        }    public static boolean checkID(String newNum) {
            return false;
        }    private static boolean validateIDForConvert(String id) {
            if (id==null || id.length()==0) {return false;}
            if (!(id.length()==OLD_15_BITS_ID_LEN || id.length()==OLD_17_BITS_ID_LEN)) {return false;}
            // all digital number consisted.
            for (int i=0;i<id.length();i++ ) {
                if(id.charAt(i)<'0'||id.charAt(i)>'9') {
                    return false;
                }
            }
            return true;
        }    private static String convert(String numToNew) throws Exception {
            int num = 0;
            int year = Integer.valueOf(numToNew.substring(6, 10)).intValue();
            int month = Integer.valueOf(numToNew.substring(10, 12)).intValue();
            int day = Integer.valueOf(numToNew.substring(12, 14)).intValue();        if( (year < 1800) || (month < 1 || month > 12)||(day < 1 || day > 31) ) {
                throw new Exception("Invalid birthday");
            }        for (int i = 18; i > 1; i--)
                num += (int) Math.pow(2, i - 1) % 11
                        * Integer.valueOf("" + numToNew.charAt(18 - i)).intValue();
            num %= 11;        String vcode = "";
            switch (num) {
                case 0:
                    vcode = "1";
                    break;
                case 1:
                    vcode = "0";
                    break;
                case 2:
                    vcode = "x";
                    break;
                default:
                    vcode = 12 - num + "";
                    break;
            }
            return numToNew + vcode;
        }
    }
      

  5.   

    sorry, 没有QQ.
    愿意的话可以给我发邮件 [email protected]
      

  6.   

    那就 E_Mail 吧,其实我也很怕 QQ 烦我的 E_Mail 是 [email protected]
    (刚才的 TestIdLiveUp.java 找不到 TestCase 类,类库不是很熟,不知道是不是系统类)
      

  7.   

    在CSDN上看到最让人感动的贴子。大家都来学习 xiaohaiz(xiaohaiz) 的敬业,onefox(一品狐) 的谦虚!!!顶!!