Assert Methods

สำหรับคนที่เคยลองเขียน Unit test มาบ้างแล้ว เคล็ดลับสำคัญของการเขียน Unit test ด้วย JUnit คือ “การเลือกใช้ assert แบบต่างๆที่มีอยู่ใน class org.junit.Assert” ในบทความนี้เราจะลงลึกไปดูซิว่ามี assert อะไรบ้างที่เราสามารถนำมาใช้ให้เหมาะกับการทำ Unit test ของเรา

รายชื่อ assert methods ที่เราจะมาเล่นกัน

  • assertArrayEquals()
  • assertEquals()
  • assertTrue() + assertFalse()
  • assertNull() + assertNotNull()
  • assertSame() + assertNotSame()
  • assertThat()

หลังจากที่เรารู้ว่ามี assert อะไรให้ใช้บ้างแล้ว เราก็มาเจาะดูซิว่าในแต่ละตัวมันทำงานยังไงและเราจะเรียกใช้มันแบบไหน โดยตัวอย่างนี้จะจำลอง class ขึ้นมาหนึ่งตัวชื่อ MyUnit ซึ่งเราไม่สนใจมันว่าใส้มันเขียนยังไง เราจะเน้นว่าถ้ามี method ใน class นี้เรา Unit test มันยังไงบ้างพอ

assertArrayEquals()

สำหรับ method นี้มีไว้สำหรับทดสอบ array 2 ตัวว่า “เท่ากัน” หรือไม่ โดยคำว่า “เท่ากัน” นี้หมายถึง array 2 ตัวนี้ต้องมี “จำนวนสมาชิก” เท่ากัน และ “สมาชิกในแต่ละตำแหน่งต้องมีค่าเท่ากัน” ด้วย

ในการทดสอบว่า “สมาชิกในแต่ละตำแหน่งต้องมีค่าเท่ากัน” หรือไม่นั้น สมาชิกจะถูกทดสอบด้วย method ที่ชื่อว่า equals โดยจะทดสอบตัวต่อตัวในแต่ละตำแหน่งของสมาชิกใน array นั้นหมายความว่าไม่ใช่แค่มีสมาชิกเท่ากันเท่านั้น แต่ลำดับของสมาชิกต้องตรงกันเป๊ะด้วย

ตัวอย่าง: ต้องการทำ Unit test กับ method ชื่อ getTheStringArray() ว่า return ค่าเท่ากับ {“one”, “two”, “three”} ไหม

import org.junit.Test;
import static org.junit.Assert.*;

public class MyUnitTest {

    @Test
    public void testGetTheStringArray() {
        MyUnit myUnit = new MyUnit();

        String[] expectedArray = {"one", "two", "three"};

        String[] resultArray =  myUnit.getTheStringArray();

        assertArrayEquals(expectedArray, resultArray);
    }
}

อธิบาย code:
1. สร้าง array ชื่อ expectedArray
ที่มีข้อมูลตามที่เราคาดหวังไว้คือ {“one”, “two”, “three”}
2. เรียก getTheStringArray() แล้วเก็บค่าใส่ตัวแปรชื่อ resultArray
3. นำตัวแปรทั้งคู่มาเข้า assertArrayEquals(expectedArray, resultArray) เพื่อทดสอบว่าผ่าน Unit test หรือไม่

ซึ่งถ้า array ทั้งคู่มีค่าเท่ากัน process การ Unit test ก็จะผ่านไปได้โดยไม่มีอะไร แต่ถ้าเกิดไม่เท่ากันก็จะมีเกิด exception และหยุดการ Unit test ใน testGetTheStringArray() ไป

assertEquals()

เป็นการ Unit test ระหว่าง object กับ object โดยผ่านการเรียก equals()
ตัวอย่าง: ทำการ Unit test ตัว concatenate() ว่าสามารถต่อ String กันได้ถูกต้องไหม

import org.junit.Test;
import static org.junit.Assert.*;

public class MyUnitTest {

    @Test
    public void testConcatenate() {
        MyUnit myUnit = new MyUnit();

        String result = myUnit.concatenate("one", "two");

        assertEquals("onetwo", result);
    }
}

อธิบาย code:
1. เรียก concatenate(“one”, “two”) ให้ผลลัพท์เก็บไว้ที่ตัวแปร result
2. นำตัวแปรทั้งคู่มาเข้า assertEquals(“onetwo”, result) เพื่อทดสอบว่าผ่าน Unit test หรือไม่

เหมือนกับ assertArray ถ้าทั้งคู่มีค่าเท่ากัน process การ Unit test ก็จะผ่านไปได้ ถ้าไม่ก็เกิด exception จากตัวอย่างนี้เป็นการเปรียบเทียบ object ของ String แต่จริงๆแล้วตัว assertEquals สามารถเปรียบเทียบกับ object ของ class ใดๆก็ได้รวมไปถึงพวก primitive เช่นพวก int หรือ float ก็ทำได้เช่นกัน

assertTrue() + assertFalse()
เป็น method สำหรับทำ Unit test แบบใช้ตัวแปรตัวเดียวว่ามันเป็น true หรือ false

ตัวอย่าง: ทำการ Unit test ตัว getTheBoolean()

import org.junit.Test;
import static org.junit.Assert.*;

public class MyUnitTest {

    @Test
    public void testGetTheBoolean() {
        MyUnit myUnit = new MyUnit();

        assertTrue (myUnit.getTheBoolean());

        assertFalse(myUnit.getTheBoolean());
    }
}

อธิบาย code:
จะเห็นได้ว่าเราส่งผลลัพท์จาก myUnit.getTheBollean() ในตัว assertTrue() และ assertFalse() โดยตรง ซึ่งถ้า getTheBoolean() ได้ค่าเป็น true ตัว assertTrue() ก็จะผ่าน แต่ถ้าเป็น false ตัว assertFalse() ก็จะผ่าน แต่ถ้าดูที่ตัวอย่างนี้จะเห็นว่า Unit test ยังไงก็ไม่ผ่านเพราะมันจะติดที่ assertTrue() หรือ assertFalse() ไม่จุดใดก็จุดนึง

assertNull() + assertNotNull()

เป็น method สำหรับทำ Unit test แบบใช้ตัวแปรตัวเดียวอีกเช่นกัน โดยเราจะสนใจว่ามันเป็น null หรือไม่

ตัวอย่าง: ทำการ Unit test ตัว getTheObject()

import org.junit.Test;
import static org.junit.Assert.*;

public class MyUnitTest {

    @Test
    public void testGetTheObject() {
        MyUnit myUnit = new MyUnit();

        assertNull(myUnit.getTheObject());

        assertNotNull(myUnit.getTheObject());
    }
}

อธิบาย code:
คล้ายกับ assertTrue() + assertFalse() จะเห็นได้ว่าเราส่งผลลัพท์จาก myUnit.getTheObject() ในตัว assertNull() และ assertNotNull() โดยตรง ซึ่งถ้า getTheObject() ได้ค่าเป็น null ตัว assertNull() ก็จะผ่าน แต่ถ้าไม่เท่ากับ null ตัว assertNotNull() ก็จะผ่าน แต่ถ้าดูที่ตัวอย่างนี้จะเห็นว่า Unit test ยังไงก็ไม่ผ่านเพราะมันจะติดที่ assertNull() หรือ assertNotNull() ไม่จุดใดก็จุดนึง

assertSame() + assertNotSame()
สำหรับ method สองตัวนี้มีได้สำหรับทำ Unit test ว่า reference ทั้งสองตัวนี้ชี้ไปที่ object ตัวเดียวกันหรือไม่ ซึ่งมันไม่เหมือนกับ assertEquals() ซึ่งเทียบกันด้วย equals() แต่ method นี้ต้องเป็นตัวเดียวกันจริงๆเท่านั้น

ตัวอย่าง: ทำการ Unit test ตัว getTheSameObject()

import org.junit.Test;
import static org.junit.Assert.*;

public class MyUnitTest {

    @Test
    public void testGetTheSameObject() {
        MyUnit myUnit = new MyUnit();

        assertSame   (myUnit.getTheSameObject(),
                      myUnit.getTheSameObject());

        assertNotSame(myUnit.getTheSameObject(),
                      myUnit.getTheSameObject());
    }
}

อธิบาย code:
เราเรียก myUnit.getTheSameObject() ลงไปตรงๆที่ assertSame() และ assertNotSame() ถ้า reference ทั้งสองชี้ไปยัง object ตัวเดียวกัน assertSame() จะผ่านปกติถ้าไม่ก็จะเกิด exception ส่วน assertNotSame() ก็จะทำงานตรงกันข้าม


assertThat()

เป็น method ที่ใช้เปรียบเทียบระหว่าง object กับ org.hamcrest.Matcher โดย Unit test จะผ่านเมื่อ object นั้นต้อง match กับ Matcher ที่เราเลือก

ตัว Matcher อาจจะต้องใช้พื้นที่อธิบายกว้างซักนิด ดังนั้นเราจะอธิบายมันอีกทีในบทความหน้าครับ

แปลจาก: Assert Methods by Jakob Jenkov

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s