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 มันทำให้มันเล็กลง สวยขึ้น เจอกันตอนหน้า