ฉันจะทดสอบบริการเว็บ REST ของฉันได้อย่างไร


16

ฉันยังใหม่กับการทดสอบหน่วยฉันมีวิธีการทางเว็บที่เหลือเพียงแค่เรียก DB และเติมข้อมูล DTO รหัสหลอกคือ

public object GetCustomer(int id)
{
  CustomerDTO objCust = //get from DB
  return objCust;
}

ข้อสงสัยของฉันคือวิธีการเขียนการทดสอบสำหรับวิธีการเหล่านี้และประเภทของการทดสอบ (Integration / Unit) ที่จะรวม และสำหรับการทดสอบหน่วยจำเป็นต้องกดฐานข้อมูลหรือไม่ หากเป็นและฉันส่งรหัสลูกค้าและยืนยันน้อยข้อมูลอาจเปลี่ยนแปลงได้ในที่สุดทำให้เกิดความล้มเหลว

ฉันคิดว่าฉันขาดอะไรบางอย่างที่นี่เพื่อทำความเข้าใจแนวคิดเหล่านี้


5
ในรหัสที่คุณโพสต์สิ่งที่ต้องทดสอบคือ: (1) คุณสามารถโทรหา GetCustomer โดยมี int เป็นพารามิเตอร์ (2) ส่งคืนออบเจค CustomerDTO หรือไม่ (3) วัตถุนั้นมีประชากรจากฐานข้อมูลตามที่คาดไว้หรือไม่ (4) พฤติกรรมที่คาดหวังเกิดขึ้นหากเรียกใช้ด้วย int ที่ไม่สอดคล้องกับลูกค้าที่ถูกต้องหรือไม่? ยังไม่มีส่วนเกี่ยวข้องกับ REST เมื่อคุณพร้อมที่จะเขียนโค้ดที่ตอบสนองต่อคำขอ RESTful คุณจะต้องทำการทดสอบ
DavidO

@DavidO: "วัตถุนั้นบรรจุจากฐานข้อมูลอย่างที่คาดไว้หรือไม่" เป็นเด็ดไม่ได้ทดสอบหน่วย (ในเรื่องที่เกี่ยวกับรหัสของ OP) นั่นคือการทดสอบบูรณาการ
Flater

ใช่คุณถูกต้อง. ถ้าฉันสามารถย้อนกลับไปและเปลี่ยนความคิดเห็นเพื่อพูดถึงว่าในการทดสอบการรวมคุณจะตรวจสอบองค์ประกอบฐานและเยาะเย้ยมันฉันจะทำการแก้ไขนั้น แต่หน้าต่างแก้ไขสำหรับความคิดเห็นถ้า 5 นาทีและความคิดเห็นถูกทำให้หก ปีที่แล้ว :)
DavidO

คำตอบ:


18

ในขณะที่การทดสอบหน่วยคุณไม่ได้คาดหวังว่าจะทดสอบกับฐานข้อมูลหรืออย่างน้อยก็ไม่ใช่ฐานข้อมูลที่คุณไม่ได้เตรียมไว้สำหรับการทดสอบหน่วย การทดสอบกับฐานข้อมูลและโดยทั่วไปการทดสอบเลเยอร์ต่าง ๆ ของแอปพลิเคชันของคุณในเวลาเดียวกันจะถูกมองว่าเป็นการทดสอบการรวมเข้าด้วยกัน ด้วยการทดสอบหน่วยคุณควรทดสอบเฉพาะวิธีที่คุณทำสิ่งที่มันส่งกลับขึ้นอยู่กับพารามิเตอร์ที่แตกต่างกันและเมื่อ (หรือไม่) ควรล้มเหลว

เป็นที่คาดหวังอย่างมากว่าในวิธีการของคุณคุณโทรไปยังวิธีการXจากชั้นเรียนอื่น ๆ คุณไม่ได้ทดสอบวิธีการXเหล่านี้ดังนั้นสิ่งที่คุณต้องทำคือการจำลองวิธีการเหล่านี้

ฉันคิดว่าคุณกำลังเขียนโค้ดของคุณใน Java ในกรณีนี้คุณมีกรอบการเยาะเย้ยที่ยอดเยี่ยมเช่นMockitoซึ่งอาจเป็นประโยชน์กับคุณ ไม่ว่าคุณจะใช้กรอบการเยาะเย้ยหรือไม่ก็เป็นทางเลือกของคุณฉันจะบอกว่าพวกเขาจะประหยัดเวลาได้มากและอย่างที่ฉันพูดถึงอย่างน้อยก็ไม่ซับซ้อน

หากคุณเพียงต้องการที่จะเขียนจำลองของคุณเองเพื่อทดลองสมมติว่าคุณมีCustomerRepositoryคลาสต่อไปนี้:

public class CustomerRepository {
 public CustomerDTO getCustomer(int id) {
   ...
 }
}

คุณสามารถเขียนCustomerRepositoryคลาสที่เยาะเย้ยและสกปรกได้ด้วยวิธีต่อไปนี้:

public class MockedCustomerRepository extends CustomerRepository {
 public boolean bThrowDatabaseException;
 public boolean bReturnNull;
 public boolean bReturnCustomerWrongId;
 public boolean bReturnCustomerWithId;
 public CustomerDTO getCustomer(int id) {
  if(bThrowDatabaseException) { 
    throw new DatabaseException("xxx"); 
  } else if(bReturnNull) { 
    return null; 
  } else if(bReturnCustomerWrongId) { 
    throw new CustomerNotExistException(id);
  } else if(bReturnCustomerWithId) { 
    return new CustomerDTO(id); 
  }
 }
}

จากนั้นในกรณีทดสอบของคุณคุณจะแทนที่อินสแตนซ์ "มาตรฐาน" ของคุณCustomerRepositoryด้วยอินสแตนซ์ที่เยาะเย้ยซึ่งจะช่วยให้คุณทดสอบวิธีการของคุณสำหรับผลลัพธ์ต่างๆของgetCustomer:

public class CustomerRestTest {
  public void testGetCustomer_databaseFailure() {
    MockedCustomerRepository dto = new MockedCustomerRepository();
    dto.bThrowDataBaseException = true;
    yRestClass rest = new MyRestClass();
    rest.dto = dto;
    rest.getCustomer(0);
    // depending on what you do in your getCustomer method, you should check if you catched the exception, or let it pass, etc.. Make your assertions here

  public void testGetCustomer_customerNotExist() {
    // etc.
  }
}

โดยทั่วไปวิธีการทดสอบทุกวิธีควรทดสอบอย่างเดียวเท่านั้นสิ่งนี้จะช่วยให้การทดสอบของคุณมีขนาดเล็กและมุ่งเน้นไปที่งานเดียว

ฉันจะทำซ้ำ :-) การเขียนคลาสที่เยาะเย้ยทั้งหมดต้องใช้เวลาพอสมควรตามที่คุณเห็น ลองพิจารณาใช้กรอบการทำงานที่เยาะเย้ยยิ่งเขียนรหัสน้อยลงมีข้อผิดพลาดน้อยลงใช่ไหม การเยาะเย้ยวิธีการที่ทำให้เกิดข้อยกเว้นหรือส่งกลับค่าที่กำหนดสำหรับพารามิเตอร์ที่กำหนดคือชิ้นส่วนของเค้กและใช้เวลา 2 หรือ 3 บรรทัด (ด้วย mockito อย่างน้อย)

หวังว่าจะช่วยทดสอบวิธี REST ของคุณ


4
โดยปกติคุณจะไม่มีตรรกะภายในคลาส DTO โดยเฉพาะอย่างยิ่งไม่มีสิ่งใดที่โต้ตอบกับที่เก็บข้อมูลของคุณ
JustAnotherUserYouMayKnowOrNot

1
มันเป็นเพียงตัวอย่าง แต่คุณพูดถูก ฉันจะเปลี่ยนตัวอย่างเพื่อให้สอดคล้องกับทฤษฎี
Jalayn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.