2015-07-02 18 views
5

Tôi đang cố gắng viết kiểm tra tích hợp cho ứng dụng scala của mình (với akka-http). Tôi đang gặp một vấn đề, mà tôi không thể tìm ra giải pháp.Thay thế giá trị trường của đối tượng lồng nhau động

lớp Trường hợp của tôi là như sau:

case class Employee(id:Long, name:String, departmentId:Long, createdDate:Timestamp) extends BaseEntity 
case class EmployeeContainer(employee:Employee, department:Department) extends BaseEntity 

Tôi có một phương pháp như thế này

trait BaseTrait[E<:BaseEntity, C <: BaseEntity]{ 
    def getById(id:Long): Future[List[C]] = { 
     //query from db and return result. 
    } 

    def save(obj:E) = { 
     //set the createDate field to the current timestamp 
     //insert into database 
    } 

} 

tôi có thể mở rộng lớp học của tôi với BaseTrait và chỉ cần ghi đè lên các phương pháp GetById(). Phần còn lại của các lớp được cung cấp bởi khung nội bộ của chúng tôi.

class MyDao extends BaseTrait[Employee, EmployeeContainer] { 
    override def getById(id:Long) = { 
     for { 
     val emp <- getFromDb(id) 
     val dept <- DeptDao.getFromDb(emp.departmentId) 
     val container = EmployeeContainer(emp,dept) 
     } yield(container) 
    } 
} 

Vì vậy, trong lớp còn lại, tôi sẽ nhận được phản hồi là EmployeeContainer. Vấn đề bây giờ tôi đang phải đối mặt là, ngày sửa đổi được tự động cập nhật với dấu thời gian hiện tại. Vì vậy, khi tôi lấy lại kết quả, dấu thời gian trong đối tượng mà tôi đã chuyển đến phương thức save() sẽ được ghi đè bằng thời gian hiện tại. Khi tôi viết test case, tôi cần phải có một đối tượng để so sánh. Nhưng dấu thời gian của đối tượng đó và đối tượng tôi nhận được sẽ không bao giờ giống nhau.

Có cách nào, trong đó tôi có thể thay thế tất cả sự xuất hiện của createDate với giá trị đã biết của dấu thời gian để tôi có thể so sánh nó trong testcase của tôi? Vấn đề chính là tôi không thể dự đoán cấu trúc của container (nó có thể có nhiều trường hợp lớp (lồng nhau hoặc bằng phẳng) có hoặc không có các trường createDate).

Tôi có thể thay thế trường bằng cách sử dụng reflection nếu nó nằm trong lớp vỏ chính, nhưng không thể làm cho các cấu trúc lồng nhau.

Trả lời

0

Có thể bạn cần sử dụng một số cho số Inversion of Control. Vấn đề chính của bạn là bạn đang gọi db trực tiếp: val emp <- getFromDb(id) và do đó không kiểm soát được thử nghiệm của các giá trị được nhận. Việc gọi DB trên một thử nghiệm đơn vị cũng được cho là một ý tưởng tồi, vì nó mở rộng đơn vị cho toàn bộ lớp cơ sở dữ liệu. Bạn muốn thử nghiệm một đơn vị nhỏ, khép kín.

Một giải pháp đơn giản là gói gọn các cuộc gọi DB của bạn dưới dạng giao diện và chuyển một phiên bản của giao diện đó. Ví dụ:

class MyDao extends BaseTrait[Employee, EmployeeContainer](val dbCall: Long => Employee) { 
    override def getById(id:Long) = { 
     for { 
     val emp <- dbCall(id) 
     val dept <- DeptDao.getFromDb(emp.departmentId) 
     val container = EmployeeContainer(emp,dept) 
     } yield(container) 
    } 
    } 

Sau đó, bạn chỉ có thể sử dụng new MyDao(getFromDb) cho mã bình thường và val testDao = new MyDao(id => Employee(id, myFixedName, myFixedDeptID, myFixedTestDate)) từ mã kiểm tra.

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