Adding a bit of error handling

และเป็นอีกครั้งที่เราต้องเพิ่ม test ใหม่เข้าไปในระบบของเราและสิ่งสุดท้ายที่เราจะทำคือการจัดการแจ้ง error เมื่อเราพยายาม evaluate template ด้วยการส้งตัวแปรที่ไม่มีค่าเข้าไปดังนั้นอย่ารอช้าเรามาดูกันว่าเราจะจัดการกับ error เหล่านั้นได้อย่างไร

Expecting an exception
คำถามคือเราจะเขียน Unit Test ที่ให้สำหรับตรวจสอบว่า exception ที่เราคาดหวังถูก throw ออกมาจากโค้ดบล๊อก try – catch ที่เราเขียนไว้ ตัวอย่างของโค้ดในส่วน 2.14 คือรูปแบบพื้นฐานที่เราใช้สำหรับการทดสอบ exception-throwing ใน JUnit

   @Test
   public void missingValueRaisesException() throws Exception {
       try {
           new Template("${foo}").evaluate();
           fail("evaluate() should throw an exception if "
                   + "a variable was left without a value!");
       } catch (MissingValueException expected) {
       }
   }

สิ่งที่เรานิยมทำกันคือการใส่ fail เมธอดลงไปหลังจากการพยายามเรียก evaluate() ที่จะทำให้เกิด exception โดยการใส่ fail ไว้ด้านหลังแบบนี้แปลว่า “ถ้าไอ้โค้ด new Template(“${foo}”).evaluate(); สามารถทำงานผ่านฉลุยข้ามไปอีกบรรทัดได้แสดงว่ามีบางอย่างผิดปกติไปจากที่มันควรจะเป็นแล้วพี่น้อง” และส่วนต่อไปที่เราจะใส่ครอบไว้เพื่อจับการทำงานคือการ catch exception ที่เราคาดว่าจะเกิดจากการเรียก evaluate แบบผิดๆนี้ ส่วน error อื่นๆที่ไม่เกี่ยวข้องเราจะไม่สนใจมัน เพราะถ้ามี error อื่นๆเกิดขึ้นมันจะหมายความว่าเราทำอะไรผิดเพิ่มขึ้นไปอีกและ exception อื่นๆเหล่านั้นจะถูกจับได้โดยตัว JUnit เอง
ตอนนี้เราได้ test ที่ fail มาอีกหนึ่งอันแล้วต่อไปเราจะเริ่มแก้มันไปตามขั้นตอน โดยสิ่งแรกคือทำให้มัน compile ได้ก่อนดังนั้นสิ่งแรกที่เราจะทำคือการสร้าง MissingValueException class

public class MissingValueException extends RuntimeException {
       // this is all we need for now
}

และแน่นอนว่าหลังจากเพิ่มคลาสนี้เข้าไปแล้วเราพยายาม run test สิ่งที่ได้คือ แดงงงงงงงง ก็อย่างว่ามันต้องเป็นแบบนี้อยู่แล้วดังนั้นอย่ารอช้าซ่อมกันต่อไปโดยการเพิ่มอไรบางอย่างเข้าไปเพื่อตรวจสอบเรื่อง missing variables
ซึ่งช่วงของการเพิ่ม logic นี้เข้าไปนั้นบางครั้งจะเป็นเรื่องยากสำหรับบางคนเพราะจะเริ่มคือเยอะ ว่าจะเขียนท่าไหนดีให้ออกมาสวยๆ ยืดหยุ่นมากเพียงพอ ซึ่งการคิดแบบนี้อาจทำให้เราเสียเวลาดังนั้นเพราะให้เราสามารถเดินไปข้างหน้าได้อย่างรวดเร็วเราจะคิดอีกแบบคือคิดอะไรง่ายๆ คิดแค่ให้มันทำงานได้เดี๋ยวนั้นเพื่อให้เราสามารถ test ผ่านและได้ แถบเขียวมาให้เร็วที่สุดซึ่งมันอาจจะไม่ใช่ทางออกที่ดีที่สุดแต่เราจะกลับมาแก้มันให้ดีขึ้นเรื่อยๆแต่ตอนนี้ต้องผ่านไปให้ได้ก่อน

public String evaluate() {
       String result = templateText;
       for (Entry<String, String> entry : variables.entrySet()) {
           String regex = "\\$\\{" + entry.getKey() + "\\}";
           result = result.replaceAll(regex, entry.getValue());
       }
       if (result.matches(".*\\$\\{.+\\}.*")) {
          throw new MissingValueException();
       }
       return result;
}

กรี๊ดๆเราเปลี่ยนจากแถบแดงเป็นแถบเขียวในบัดดล และสิ่งที่เราเห็นคือเราได้ evaluate เมธอดที่สามารถทำงานได้แน่ๆ แต่ตอนนี้มันอาจจะดูใหญ่ไปนิด ซึ่งแน่นอนเราจะต้อง refactor มันทำให้มันเล็กลง สวยขึ้น เจอกันตอนหน้า

Post a comment