[英]Replace field values of a nested object dynamically
I am trying to write integration test for my scala
application(with akka-http
). 我正在尝试为我的
scala
应用程序编写集成测试(使用akka-http
)。 I am running into a problem, for which I am not able to find a solution. 我遇到了一个问题,无法找到解决方案。
My Case classes are as below: 我的案例类如下:
case class Employee(id:Long, name:String, departmentId:Long, createdDate:Timestamp) extends BaseEntity
case class EmployeeContainer(employee:Employee, department:Department) extends BaseEntity
I have a method like this 我有这样的方法
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
}
}
I can extend my class with BaseTrait and just override the getById() method. 我可以使用BaseTrait扩展类,并重写getById()方法。 Rest of the layers are provided by our internal framework.
其余各层由我们的内部框架提供。
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)
}
}
So in the rest layer, I will be getting the response as the EmployeeContainer
. 因此,在其余层中,我将以
EmployeeContainer
身份获得响应。 The problem now I am facing is that, the modified date is automaticaally updated with the current timestamp. 我现在面临的问题是,修改后的日期会自动使用当前时间戳进行更新。 So, when I get back the result, the timestamp in the object I passed to save() method will be overwritten with the current time.
因此,当我取回结果时,传递给save()方法的对象中的时间戳将被当前时间覆盖。 When I write the test case, I need to have an object to compare to.
在编写测试用例时,需要有一个要比较的对象。 But the timestamp of that object and the one I get abck will never be the same.
但是该对象的时间戳和我收到的对象的时间戳永远不会相同。
Is there anyway, in which I can replace all the occurrance of createDate with a known value of timestamp so that I can compare it in my testcase? 无论如何,我可以用已知的时间戳值替换所有createDate的出现,以便可以在测试用例中进行比较吗? The main problem is that I can not predict the structure of the container (it can have multiple case classes(nested or flat) with or without createDate fields).
主要问题是我无法预测容器的结构(带有或不带有createDate字段的容器可以具有多个案例类(嵌套或平面))。
I was able to replace the field using reflection
if it comes in the main case class, but unable to do for nested structures. 如果主案例类中包含
reflection
则可以使用reflection
来替换该字段,但无法对嵌套结构进行操作。
You probably need to use some for of Inversion of Control . 您可能需要将一些用于控制反转 。 Your main problem is that you are calling the db directly:
val emp <- getFromDb(id)
and thus have no control on a test of the values that are received. 您的主要问题是直接调用数据库:
val emp <- getFromDb(id)
,因此无法控制对接收到的值的测试。 Calling the DB on a unit test is also arguably a bad idea, since it expands the unit to the entire database layer. 在单元测试中调用DB也是一个坏主意,因为它将单元扩展到整个数据库层。 You want to test a small, self-contained unit.
您想测试一个小的独立设备。
A simple solution is to encapsulate your DB calls as an interface and pass an instance of that interface. 一个简单的解决方案是将您的数据库调用封装为一个接口,并传递该接口的实例。 For instance:
例如:
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)
}
}
Then you can simply use new MyDao(getFromDb)
for normal code and val testDao = new MyDao(id => Employee(id, myFixedName, myFixedDeptID, myFixedTestDate))
from test code. 然后,您可以简单地将
new MyDao(getFromDb)
用于常规代码,并从测试代码中使用val testDao = new MyDao(id => Employee(id, myFixedName, myFixedDeptID, myFixedTestDate))
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.