集合中的 Grails 实例修改
Grails instance modification in collection
我在两个类似的 Grails 3.3.5 测试用例中观察到不同的行为。两种情况的区别是:
- 在第一个测试用例中,规范创建了一个测试对象,将其交给控制器,控制器将其添加/放入他的两个集合
objects1
和 objects2
。在规范中修改对象时,更改适用于 objects1
和 objects2
。
- 在第二个测试用例中,controller自己创建了一个对象,放到了他的两个集合中。当我要求控制器从第一个集合 (
objects1
) 传递对象,然后在规范中修改该对象时,更改仅应用于 objects1
,但不会应用于另一个集合 [=14] =].
我的问题是:根据 Java 和 Groovy 的面向对象范例,我希望这两个测试的行为都像第一个测试。为什么会有差异,具体取决于创建对象的 class?
为了清楚起见,我的代码示例如下。域名 class:
class MyTestObject {
String value
static constraints = {
}
MyTestObject(){
value = "initialized"
}
void edit(){
value = "edited"
}
String getValue(){
value
}
}
控制器class:
class MyTestController {
def index() { }
Map<Integer, MyTestObject> objects1
Map<Integer, MyTestObject> objects2
MyTestController(){
objects1 = new HashMap<>()
objects2 = new HashMap<>()
}
void addObject(){
int count = objects1.size()
objects1.put(count, new MyTestObject())
objects2.put(count, new MyTestObject())
}
void addObject(MyTestObject testObject){
int count = objects1.size()
objects1.put(count, testObject)
objects2.put(count, testObject)
}
MyTestObject getObjectFromCollection1(int atPosition){
if (0 > atPosition || atPosition > objects1.size()-1){
return
}
objects1.get(atPosition)
}
MyTestObject getObjectFromCollection2(int atPosition){
if (0 > atPosition || atPosition > objects2.size()-1){
return
}
objects2.get(atPosition)
}
void updateObjectInCollection1(int index, MyTestObject object){
objects1.put(index, object)
}
}
规格是:
import grails.testing.web.controllers.ControllerUnitTest
import spock.lang.Specification
class MyTestControllerSpec extends Specification implements ControllerUnitTest<MyTestController> {
int index
def setup(){
index = 0
}
void "case 1: external object instantiation"() {
MyTestController controllerLocal = new MyTestController()
MyTestObject object = new MyTestObject()
controllerLocal.addObject(object)
object.edit()
MyTestObject afterEditInCollection1 = controllerLocal.getObjectFromCollection1(index)
MyTestObject afterEditInCollection2 = controllerLocal.getObjectFromCollection2(index)
expect:
"edited" == object.getValue()
"edited" == afterEditInCollection1.getValue()
"edited" == afterEditInCollection2.getValue()
}
void "case 2: internal object instantiation"() {
MyTestController controllerLocal = new MyTestController()
controllerLocal.addObject()
MyTestObject toBeEditedLocally = controllerLocal.getObjectFromCollection1(index)
toBeEditedLocally.edit()
MyTestObject afterEditInCollection1 = controllerLocal.getObjectFromCollection1(index)
MyTestObject afterEditInCollection2 = controllerLocal.getObjectFromCollection2(index)
expect:
"edited" == toBeEditedLocally.getValue()
"edited" == afterEditInCollection1.getValue()
"edited" == afterEditInCollection2.getValue()
}
def cleanup() {
}
}
Why is there a difference, depending on which class is creating the
object?
创建对象的 class 没有区别。该问题与创建实例的位置无关。问题是,在 addObject()
中,您正在创建 2 个单独的对象,将其中一个添加到 objects1
,另一个添加到 objects2
。在 addObject(MyTestObject)
中,您正在向 2 Map
.
中的每一个添加相同的 MyTestObject
实例
void addObject(){
int count = objects1.size()
objects1.put(count, new MyTestObject())
objects2.put(count, new MyTestObject())
}
void addObject(MyTestObject testObject){
int count = objects1.size()
objects1.put(count, testObject)
objects2.put(count, testObject)
}
如果您将 addObject()
更改为如下所示,您的测试都会通过:
void addObject(){
int count = objects1.size()
def newTestObject = new MyTestObject()
objects1.put(count, newTestObject)
objects2.put(count, newTestObject)
}
我在两个类似的 Grails 3.3.5 测试用例中观察到不同的行为。两种情况的区别是:
- 在第一个测试用例中,规范创建了一个测试对象,将其交给控制器,控制器将其添加/放入他的两个集合
objects1
和objects2
。在规范中修改对象时,更改适用于objects1
和objects2
。 - 在第二个测试用例中,controller自己创建了一个对象,放到了他的两个集合中。当我要求控制器从第一个集合 (
objects1
) 传递对象,然后在规范中修改该对象时,更改仅应用于objects1
,但不会应用于另一个集合 [=14] =].
我的问题是:根据 Java 和 Groovy 的面向对象范例,我希望这两个测试的行为都像第一个测试。为什么会有差异,具体取决于创建对象的 class?
为了清楚起见,我的代码示例如下。域名 class:
class MyTestObject {
String value
static constraints = {
}
MyTestObject(){
value = "initialized"
}
void edit(){
value = "edited"
}
String getValue(){
value
}
}
控制器class:
class MyTestController {
def index() { }
Map<Integer, MyTestObject> objects1
Map<Integer, MyTestObject> objects2
MyTestController(){
objects1 = new HashMap<>()
objects2 = new HashMap<>()
}
void addObject(){
int count = objects1.size()
objects1.put(count, new MyTestObject())
objects2.put(count, new MyTestObject())
}
void addObject(MyTestObject testObject){
int count = objects1.size()
objects1.put(count, testObject)
objects2.put(count, testObject)
}
MyTestObject getObjectFromCollection1(int atPosition){
if (0 > atPosition || atPosition > objects1.size()-1){
return
}
objects1.get(atPosition)
}
MyTestObject getObjectFromCollection2(int atPosition){
if (0 > atPosition || atPosition > objects2.size()-1){
return
}
objects2.get(atPosition)
}
void updateObjectInCollection1(int index, MyTestObject object){
objects1.put(index, object)
}
}
规格是:
import grails.testing.web.controllers.ControllerUnitTest
import spock.lang.Specification
class MyTestControllerSpec extends Specification implements ControllerUnitTest<MyTestController> {
int index
def setup(){
index = 0
}
void "case 1: external object instantiation"() {
MyTestController controllerLocal = new MyTestController()
MyTestObject object = new MyTestObject()
controllerLocal.addObject(object)
object.edit()
MyTestObject afterEditInCollection1 = controllerLocal.getObjectFromCollection1(index)
MyTestObject afterEditInCollection2 = controllerLocal.getObjectFromCollection2(index)
expect:
"edited" == object.getValue()
"edited" == afterEditInCollection1.getValue()
"edited" == afterEditInCollection2.getValue()
}
void "case 2: internal object instantiation"() {
MyTestController controllerLocal = new MyTestController()
controllerLocal.addObject()
MyTestObject toBeEditedLocally = controllerLocal.getObjectFromCollection1(index)
toBeEditedLocally.edit()
MyTestObject afterEditInCollection1 = controllerLocal.getObjectFromCollection1(index)
MyTestObject afterEditInCollection2 = controllerLocal.getObjectFromCollection2(index)
expect:
"edited" == toBeEditedLocally.getValue()
"edited" == afterEditInCollection1.getValue()
"edited" == afterEditInCollection2.getValue()
}
def cleanup() {
}
}
Why is there a difference, depending on which class is creating the object?
创建对象的 class 没有区别。该问题与创建实例的位置无关。问题是,在 addObject()
中,您正在创建 2 个单独的对象,将其中一个添加到 objects1
,另一个添加到 objects2
。在 addObject(MyTestObject)
中,您正在向 2 Map
.
MyTestObject
实例
void addObject(){
int count = objects1.size()
objects1.put(count, new MyTestObject())
objects2.put(count, new MyTestObject())
}
void addObject(MyTestObject testObject){
int count = objects1.size()
objects1.put(count, testObject)
objects2.put(count, testObject)
}
如果您将 addObject()
更改为如下所示,您的测试都会通过:
void addObject(){
int count = objects1.size()
def newTestObject = new MyTestObject()
objects1.put(count, newTestObject)
objects2.put(count, newTestObject)
}