2017-09-18 15 views
5

Tôi đang cố gắng để kiểm tra một lớp dịch vụ (trách nhiệm gọi lớp kho và thực hiện một số hoạt động nếu cần thiết), về cơ bản, đây là lớp tôi đang cố gắng để kiểm traGiả lập một cuộc gọi phương thức trong cùng một lớp mà tôi đang thử nghiệm, có thực sự là mã không?

class CarServiceImpl{ 
    public Car findById(String id){ 
     //call repository layer to find a car 
    } 

    public void deleteById(String id){ 
     Car car = this.findById(id); 
     if(car != null){ 
      //Call repository layer to update the car 
     }else{ 
      Throw NotFOundException(); 
     } 
    } 
} 

Như bạn có thể thấy tôi gọi phương thức findById trên phương thức deleteById, vì vậy các câu hỏi của tôi là.

  1. thực sự là mã để gọi phương thức trên cùng một lớp? Tôi không nghĩ rằng tôi nên tạo một lớp học riêng biệt để tìm một chiếc xe bằng id.

  2. làm thế nào tôi có thể thử các cuộc gọi đến "findById" vào phương pháp "deleteById", nếu tôi sử dụng Mockito.when(carServiceImpl.findById("car1")).thenReturn(carModel); nó ảnh tĩnh gọi phương thức vì vậy tôi sẽ cần phải thử cuộc gọi đến respository cho việc tìm kiếm bằng id quá, thậm chí khi tôi đã thử nghiệm phương thức findById.

+0

Còn việc rời khỏi thao tác 'findById' đối với người gọi' deleteById' thì sao? Nếu any1 vượt qua một id không tồn tại, kho lưu trữ sẽ ném một ngoại lệ thích hợp và 'CarServiceImpl' của bạn có thể bắt và biến đổi (nếu cần) ngoại lệ đó trong ứng dụng của bạn hiểu. – pedromss

Trả lời

4

này không nhất thiết phải là một mùi và bạn có thể phần nào mock Car như vậy:

String carId = "..."; 
Car car = ...; 

CarServiceImpl car = mock(CarServiceImpl.class); 
when(car.findById(carId)).thenReturn(car);  
when(car.deleteById(carId)).thenCallRealMethod(); 

Nhưng nếu bạn có thể cho phép deleteById() để thực hiện 'phương pháp thực' sau đó thử nghiệm của bạn phải đã có một kho lưu trữ trong trường hợp cho phép findById() là một 'cuộc gọi thực sự' rất đơn giản và cải thiện chất lượng của phạm vi kiểm tra của bạn tại ~ không mất thêm chi phí. Thực tế là bạn đã thử nghiệm findById() không có nghĩa là bạn không nên kiểm tra lại lần nữa, gián tiếp, như một phần của deleteById().

tôi sẽ đề nghị bạn làm một trong hai hoặc cả hai trong những cách sau:

  • Đơn vị kiểm tra Car bằng cách cho nó một chế giễu repository và sử dụng kỳ vọng chế giễu và xác minh để kiểm tra tất cả các phương thức của nó
  • chức năng/Chấp nhận kiểm tra Car bằng cách cho nó một kho lưu trữ thực và sử dụng các lời gọi thực sự trên cửa hàng bên dưới để xác nhận kết quả thực tế cho từng phương pháp của nó

Trên một lưu ý riêng biệt, tôi đoán ý tưởng tiêm một kho lưu trữ vào một đối tượng miền là một cách sử dụng có chủ ý mẫu "bản ghi hoạt động" trong đó các thực thể của bạn biết cách tự CRUD. Điều này có thể được coi là một mùi mã; nó vi phạm SRP và có thể được tổ chức để trở thành một mối quan tâm phân tách nghèo nàn bởi vì đối tượng miền biết về hai điều: trạng thái riêng của nó và làm thế nào để duy trì chính nó.

+0

Câu trả lời hay, và để lại một chút chỗ cho tôi nữa ;-) – GhostCat

1

Bạn muốn thiết lập thử nghiệm và mã thử nghiệm của mình trở nên "tối giản" nhất có thể. Theo nghĩa đó, câu trả lời khác là chính xác khi nói: nếu bạn có thể kiểm tra deleteById() mà không cần thiết lập đặc biệt thì hãy thực hiện điều đó.

Và nó sẽ chỉ ra rằng findById() là chính nó là một điều "lớn" đòi hỏi rất nhiều thiết lập thử nghiệm - sau đó tôi thà lùi lại và xem xét đưa nội dung của phương pháp này vào một lớp học riêng biệt của CarIdentityService.

Ý nghĩa: rất thường xuyên khi chúng tôi bắt đầu thực hiện thử nghiệm phức tạp hơn - câu trả lời hay hơn là lùi lại và thay đổi thiết kế mã sản xuất của chúng tôi. Trong trường hợp của bạn, bạn có thể muốn đẩy toàn bộ mã findById() vào một lớp riêng biệt - và bây giờ bạn có thể chỉ cần giả lập đối tượng công cụ tìm đó trong lớp CarService của bạn.

Và chỉ để ghi lại: CarIdentityService có thể là lớp địa phương hoặc nội bộ là CarService. Nhưng giới thiệu nó có thể cho phép bạn sắp xếp hợp lý việc triển khai và tránh xâm nhập vào công việc gián điệp.

+0

Làm rõ về cách tái cấu trúc cuộc gọi tìm kiếm. – glytching

+0

Cảm ơn bạn đã quay trở lại nhanh chóng ;-) – GhostCat

+0

Cảm ơn bạn đã trả lời câu hỏi của bạn, ví dụ tuyệt vời khi tôi cần tách mã cho lớp khác nhưng nghĩ rằng tôi chỉ gắn bó với một lớp trong trường hợp này –

Các vấn đề liên quan