Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 集合中的Grails实例修改_Java_Unit Testing_Grails - Fatal编程技术网

Java 集合中的Grails实例修改

Java 集合中的Grails实例修改,java,unit-testing,grails,Java,Unit Testing,Grails,我在两个类似的Grails3.3.5测试用例中观察到了不同的行为。这两种情况的区别是: 在第一个测试用例中,规范创建一个测试对象,将其交给控制器,控制器将其添加/放入他的两个集合objects1和objects2。在等级库中修改对象时,更改同时适用于objects1和objects2 在第二个测试用例中,控制器本身创建一个对象,并将其放入他的两个集合中。当我要求控制器从第一个集合(objects1)交付对象,然后在规范中修改此对象时,更改仅应用于objects1,而不应用于其他集合object

我在两个类似的Grails3.3.5测试用例中观察到了不同的行为。这两种情况的区别是:

  • 在第一个测试用例中,规范创建一个测试对象,将其交给控制器,控制器将其添加/放入他的两个集合
    objects1
    objects2
    。在等级库中修改对象时,更改同时适用于
    objects1
    objects2
  • 在第二个测试用例中,控制器本身创建一个对象,并将其放入他的两个集合中。当我要求控制器从第一个集合(
    objects1
    )交付对象,然后在规范中修改此对象时,更改仅应用于
    objects1
    ,而不应用于其他集合
    objects2
我的问题是:根据Java和Groovy的面向对象范例,我希望这两个测试的行为与第一个测试类似。根据创建对象的类的不同,为什么会有差异?

为了澄清,下面是我的代码示例。域类:

class MyTestObject {

    String value

    static constraints = {
    }

    MyTestObject(){
        value = "initialized"
    }

    void edit(){
        value = "edited"
    }

    String getValue(){
        value
    }
}
控制器类:

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

}
类MyTestController{
def index(){}
映射对象1
映射对象2
MyTestController(){
objects1=新的HashMap()
objects2=新的HashMap()
}
void addObject(){
int count=objects1.size()
objects1.put(计数,新的MyTestObject())
objects2.put(计数,新的MyTestObject())
}
void addObject(MyTestObject testObject){
int count=objects1.size()
objects1.put(count,testObject)
objects2.put(计数,testObject)
}
MyTestObject getObjectFromCollection1(int-atPosition){
如果(0>atPosition | | atPosition>objects1.size()-1){
回来
}
objects1.get(atPosition)
}
MyTestObject getObjectFromCollection2(int-atPosition){
如果(0>atPosition | | atPosition>objects2.size()-1){
回来
}
objects2.get(atPosition)
}
void updateObjectInCollection1(int索引,MyTestObject对象){
objects1.put(索引,对象)
}
}
规格为:

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() {
    }

}
导入grails.testing.web.controllers.ControllerUnitTest
导入spock.lang.Specification
类MyTestControllerSpec扩展规范实现ControllerUnitTest{
整数索引
def设置(){
索引=0
}
无效“案例1:外部对象实例化”(){
MyTestController控制器本地=新的MyTestController()
MyTestObject对象=新的MyTestObject()
controllerLocal.addObject(对象)
object.edit()
MyTestObject afterEditInCollection1=controllerLocal.getObjectFromCollection1(索引)
MyTestObject afterEditInCollection2=controllerLocal.getObjectFromCollection2(索引)
期望:
“已编辑”==object.getValue()
“已编辑”==afterEditInCollection1.getValue()
“已编辑”==afterEditInCollection2.getValue()
}
无效“案例2:内部对象实例化”(){
MyTestController控制器本地=新的MyTestController()
controllerLocal.addObject()
MyTestObject ToBeedItemLocally=controllerLocal.getObjectFromCollection1(索引)
toBeEditedLocally.edit()
MyTestObject afterEditInCollection1=controllerLocal.getObjectFromCollection1(索引)
MyTestObject afterEditInCollection2=controllerLocal.getObjectFromCollection2(索引)
期望:
“已编辑”==toBeEditedLocally.getValue()
“已编辑”==afterEditInCollection1.getValue()
“已编辑”==afterEditInCollection2.getValue()
}
def cleanup(){
}
}
为什么会有差异,这取决于创建 反对

这与创建对象的类没有区别。问题与实例的创建位置无关。问题在于,在
addObject()
中,您正在创建两个单独的对象,将其中一个添加到
objects1
,另一个添加到
objects2
。在
addObject(MyTestObject)
中,您正在将相同的
MyTestObject
实例添加到2个
Map
中的每一个

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

这与您的问题无关,但是在单例控制器中使用那些
object1
object2
实例变量可能会导致并发问题。很难从您的示例中看出您实际使用它们的目的,但控制器中不会有这些功能。@JeffScottBrown是的,谢谢您的提示。这只是一个澄清的例子-我要记住这一点。哦,我真蠢。有时你需要另一双眼睛。谢谢“哦,愚蠢的我”-一点也不愚蠢。很高兴这有道理。祝你好运!