
Celsius ทำการ implement เรียบร้อยแล้ว แต่ Fahrenheit ยังไม่ได้ทำ คือเราจะทำการเขียนเทสก่อน แล้วค่อยเอาโค๊ดที่ได้ไปแปะไว้ที่ Fahrenheit ทีหลัง
ส่วนโค๊ดก็เป็นดังนี้
โค๊ดสำหรับ Calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
public interface Calculator | |
{ | |
double toCelsius(); | |
double toFahrenheit(); | |
double getValue(); | |
void setValue(double value); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
public class Celsius implements Calculator | |
{ | |
protected double c; | |
@Override | |
public double toCelsius() | |
{ | |
return this.c; | |
} | |
@Override | |
public double toFahrenheit() | |
{ | |
return ( c * 9 ) / 5 + 32; | |
} | |
@Override | |
public double getValue() | |
{ | |
return this.c; | |
} | |
@Override | |
public void setValue(double value) | |
{ | |
this.c = value; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
public class Fahrenheit | |
{ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
import static org.junit.Assert.assertEquals; | |
import org.junit.Ignore; | |
import org.junit.Test; | |
public class CalculatorTest | |
{ | |
@Test | |
public void testCtoF() | |
{ | |
Celsius celcius = new Celsius(); | |
Calculator cel = celcius; | |
cel.setValue(100); | |
assertEquals(212, cel.toFahrenheit(), 0); | |
assertEquals(100, celcius.c, 0); | |
} | |
@Test | |
public void testFtoC() | |
{ | |
throw new RuntimeException(); | |
} | |
} |
ณ จุดนี้ เวลารัน คุณก็จะได้ อันหนึ่งที่บอกว่าเทสไม่ผ่าน ที่ไม่ผ่านก็เพราะว่าทำการ
throw new RuntimeException();
แต่เราต้องการเทส function double toCelsius();
จาก interface ดังนั้นเราก็ต้องมีคลาส Fahrenheit เพื่อจะได้ทำการ implement ฟังก์ชั่น toCelsius ก่อนอื่น เราก็มาดีไซน์กันก่อนว่าจะให้ทำงานยังไง เราก็เริ่มเขียนเทสก่อนเลยครับthrow new RuntimeException(); ในที่นี้จะเป็นตัวบอกเราว่าเราทำงานไปถึงไหน มีอะไรทียังรอ. คุณอาจเขียนแบบนี้ก็ได้คือ throw new RuntimeException("Waiting for implement");
ว่าแล้วก็เขียนเทสก่อนสำหรับ Fahrenheit กันเลยครับ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Test | |
public void testFtoC() | |
{ | |
Fahrenheit fahrenheit = new Fahrenheit(); | |
Calculator fah = fahrenheit; | |
fah.setValue(212); | |
assertEquals(100,fah.toCelsius(),0); | |
assertEquals(212,fahrenheit.f , 0); | |
} |
แต่ว่าตอนนี้ก็ยังรันไม่ผ่าน เพราะคลาส Fahrenheit เราไม่ได้สร้างอะไรไว้เลย ไม่ได้ implements แม้กระทั้ง Calculator ว่าแล้วก็เริ่มกันเลยครับ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
public class Fahrenheit implements Calculator | |
{ | |
protected double f; | |
@Override | |
public double toCelsius() | |
{ | |
return ( f - 32 ) * 5 / 9 ; | |
} | |
@Override | |
public double toFahrenheit() | |
{ | |
return this.f; | |
} | |
@Override | |
public double getValue() | |
{ | |
return this.f; | |
} | |
@Override | |
public void setValue(double value) | |
{ | |
this.f = value; | |
} | |
} |
กลับมาที่ CalculatorTest.java คุณจะเห็นว่า ทุกครั้งที่เราต้องเขียนเทส เราจะสร้าง object ของ Calculator ขึ้นมารัวๆ . Junit เข้าใจวัยรุ่นตรงจุดนี้ ก็เลยสร้าง annotation อีกอันหนึ่งชื่อ @Before ซึ่งตัวนี้หมายความว่า ทุกครั้งที่ Junit จะทำการทดสอบเทสที่เราเขียนไว้ใต้ @Test , Junit จะเรียก @Before ขึ้นมาก่อนทุกครั้งไป.
โอเคแล้วมันหมายความว่าหยั่งใด ก็จะหมายความว่า หากคุณเซตอัพ @Before ไว้แล้ว คราวนี้พอจะเขียนเทสอันต่อไปก็เริ่มเขียนโค๊ดต่อจาก @Before ในส่วนของ @Test ได้เลย ไม่งงนะคนดี ไปดูโค๊ดกันเถอะตัวเอง
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javachef.core; | |
import static org.junit.Assert.assertEquals; | |
import org.junit.Before; | |
import org.junit.BeforeClass; | |
import org.junit.Ignore; | |
import org.junit.Test; | |
public class CalculatorTest | |
{ | |
private Celsius celcius; | |
private Fahrenheit fahrenheit; | |
@Before | |
public void init() | |
{ | |
celcius = new Celsius(); | |
fahrenheit = new Fahrenheit(); | |
} | |
@Test | |
public void testCtoF() | |
{ | |
Calculator cel = celcius; | |
cel.setValue(100); | |
assertEquals(212, cel.toFahrenheit(), 0); | |
assertEquals(100, celcius.c, 0); | |
} | |
@Test | |
public void testFtoC() | |
{ | |
Calculator fah = fahrenheit; | |
fah.setValue(212); | |
assertEquals(100,fah.toCelsius(),0); | |
assertEquals(212,fahrenheit.f , 0); | |
} | |
} |
เวลาเขียนเทส ควรจะเทสเป็นเรื่องๆ ไป ไม่ควรเทสหลายเรื่องในเคสเดียวกัน เพื่อเราจะหาบักได้ง่ายเวลาอะไรมีปัญหาขึ้นมา
พอถึงตรงนี้ คุณจะเริ่มคุ้นกับการเขียนเทสเคสขึ้นมาบ้างแล้ว อันที่จริง เราจะไม่เขียนโค๊ดแล้วมาเทสนะครับ แต่จะเขียนเทสก่อนแล้วค่อยโค๊ด !
แม่นแล้วครับ ศัพท์เทกนิคคือ Test-Driven Development เอาสั้นๆง่ายๆก่อนนะ แล้วเราจะลงลึกหลังเมื่อถึงเวลา แต่ตอนนี้ก็จะประมาณว่า สมมุติคุณอยากใช้โค๊ดแบบไหน ก็เขียนโค๊ดแบบนั้นลงไปในเทสเคสก่อน แล้วจึ่งค่อยทำการ implement เพื่อให้ได้ในสิ่งที่ต้องการ เหมือนโค๊ดข้างบน
โพสต่อไปเราจะมาดูกันเรื่องการเทสเรื่อง exception และ เทสว่าโปรแกรมทำงานภานในเวลาที่กำหนดหรือไม่ ! น่าสนใจใช่ไหม ไปชมโพสต่อไปกันเลย