Làm cách nào tôi có thể kiểm tra đơn vị dịch vụ web REST của mình?


16

Tôi chưa quen với thử nghiệm đơn vị, tôi có một phương pháp web REST chỉ gọi DB và điền vào DTO. Mã giả là

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

Tôi nghi ngờ là làm thế nào để viết các bài kiểm tra cho các phương pháp và loại bài kiểm tra (Tích hợp / Đơn vị) được đưa vào. Và đối với các bài kiểm tra đơn vị, nó có cần phải đánh DB không. Nếu đó là và tôi vượt qua một id khách hàng và thực hiện một vài xác nhận, dữ liệu cuối cùng có thể thay đổi dẫn đến thất bại.

Tôi nghĩ rằng tôi đang thiếu một cái gì đó ở đây để hiểu những khái niệm này.


5
Trong mã bạn đã đăng, những điều cần kiểm tra là: (1) Bạn có thể gọi GetCustomer với int là tham số không. (2) Nó có trả về một đối tượng CustomerDTO không? (3) Đối tượng đó có được sinh ra từ DB như mong đợi không. (4) Có một hành vi dự kiến ​​xảy ra nếu được gọi với một int không tương ứng với một khách hàng hợp lệ không? Không ai trong số đó phải làm với REST. Khi bạn đã sẵn sàng viết mã đáp ứng các yêu cầu RESTful, thì bạn sẽ viết các bài kiểm tra cho nó.
DavidO

@DavidO: "Đối tượng đó có được sinh ra từ DB như mong đợi không." được quyết định không phải là một bài kiểm tra đơn vị (liên quan đến mã của OP). Đó là một bài kiểm tra tích hợp.
Flater

Ư, bạn đung. Nếu tôi có thể quay lại và thay đổi nhận xét để đề cập rằng trong thử nghiệm tích hợp, bạn sẽ xác minh thành phần DB và nếu không, nó sẽ thực hiện chỉnh sửa đó, nhưng cửa sổ chỉnh sửa để nhận xét nếu 5 phút và nhận xét được thực hiện sáu những năm trước :)
DavidO

Câu trả lời:


18

Trong khi thử nghiệm đơn vị, bạn không nên thử nghiệm với cơ sở dữ liệu, hoặc ít nhất, không phải với cơ sở dữ liệu mà bạn chưa chuẩn bị để thử nghiệm đơn vị. Kiểm tra với cơ sở dữ liệu và như vậy, kiểm tra các lớp khác nhau của ứng dụng của bạn cùng một lúc thường được xem là kiểm tra tích hợp . Với các bài kiểm tra đơn vị, bạn phải kiểm tra chỉ phương thức của bạn làm gì, nó trả về tùy thuộc vào các tham số khác nhau và khi nào (hoặc không) nó sẽ thất bại.

Rất mong đợi rằng trong phương thức của bạn, bạn thực hiện các cuộc gọi đến các phương thức X từ các lớp khác. Bạn không thử nghiệm các phương thức X này, vì vậy điều bạn phải làm là giả định các phương thức này.

Tôi cho rằng bạn đang viết mã của mình bằng Java, trong trường hợp đó bạn có các khung mô phỏng tuyệt vời như Mockito có thể hữu ích cho bạn. Cho dù bạn có sử dụng khung mô phỏng hay không là lựa chọn của bạn, tôi sẽ chỉ nói rằng họ sẽ tiết kiệm cho bạn rất nhiều thời gian và ít nhất tôi đã đề cập ít nhất là không phức tạp.

Nếu bạn chỉ muốn viết giả của riêng mình để thử nghiệm, thì giả sử bạn có CustomerRepositorylớp sau :

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

Bạn có thể viết CustomerRepositorylớp nhạo báng và bẩn thỉu của riêng bạn theo cách sau:

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); 
  }
 }
}

Sau đó, trong trường hợp thử nghiệm của bạn, về cơ bản, bạn thay thế thể hiện "tiêu chuẩn" của mình CustomerRepositorybằng một thể hiện giả định sẽ cho phép bạn kiểm tra phương pháp của mình để biết các kết quả khác nhau về 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.
  }
}

Nói chung, mọi phương pháp kiểm tra chỉ nên kiểm tra một điều, điều này giúp giữ cho các bài kiểm tra của bạn nhỏ và tập trung vào một nhiệm vụ.

Tôi sẽ lặp lại nó :-) Viết cả một lớp bị chế giễu mất một thời gian như bạn thấy. Hãy xem xét việc sử dụng một khung mô phỏng, càng ít mã viết, càng ít lỗi , phải không? Mocking một phương thức đưa ra một ngoại lệ hoặc trả về một giá trị đã cho cho một tham số đã cho là một miếng bánh và mất 2 hoặc 3 dòng (ít nhất là với mockito)

Hy vọng rằng sẽ giúp kiểm tra phương pháp REST của bạn.


4
Thông thường, bạn không có logic trong các lớp DTO, đặc biệt là không có tương tác với lưu trữ dữ liệu của bạn.
JustAntherUserYouMayKnowOrNot 26/03 '

1
Đó chỉ là một ví dụ, nhưng bạn hoàn toàn đúng. Tôi sẽ thay đổi các ví dụ để chúng phù hợp hơn với lý thuyết.
Jalayn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.