2017-08-10 27 views
0

我有以下用dummy dummy groovy類編寫的測試。Groovy Expando Metaclass安裝人員訪問

@Test 
void returnPropertyIfPropertyIsAvailableOnMetaClass(){ 
    def emp=new Employee() 
    emp.metaClass.sayGutenAbend="Guten Abend" 
    assert emp.sayGutenAbend=="Guten Abend" 
    assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend") 
    emp.metaClass.setProperty(emp,"sayGutenAbend","Guten Morgen") 
    assert emp.sayGutenAbend=="Guten Morgen" 
    assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend"); 
} 

上述測試通過,而下面沒有─

@Test 
void returnPropertyIfPropertyIsAvailableOnMetaClass_Fails(){ 
    def emp=new Employee() 
    emp.metaClass.sayGutenAbend="Guten Abend" 
    assert emp.sayGutenAbend=="Guten Abend" 
    assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend") 
    emp.metaClass.sayGutenAbend="Guten Morgen" 
    assert emp.sayGutenAbend=="Guten Morgen" 
    assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend") 
} 

從前面的代碼示例是唯一的差異,設置在元類相同的屬性的新值。只是好奇。任何人都可以指出爲什麼這是這樣工作嗎?

回答

0

一旦字段與元編程創建你不需要使用metaClass重置密碼:

class Employee{} 

def emp = new Employee() 

emp.metaClass.sayGutenAbend="Guten Abend" 
assert emp.sayGutenAbend=="Guten Abend" 
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend") 

emp.sayGutenAbend="Guten Nacht" 
assert emp.sayGutenAbend=="Guten Nacht" 
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend") 

我瞎猜,出現這種情況是由於元類的某些部分正在重建,而你想要的是改變綁定到你的對象實例的那個。可能與This answer有關。


在這個片段中,重置屬性創建一個新的ThreadManagedMetaBeanProperty,因此,這種失敗:

class Employee{} 

def emp = new Employee() 
emp.metaClass.sayGutenAbend="Guten Abend" 

def metaclass1 = emp.metaClass.properties[1] 
emp.metaClass.sayGutenAbend="Guten Nacht" 

def metaclass2 = emp.metaClass.properties[1] 

assert metaclass1 == metaclass2 // fails 

雖然這個工程:

class Employee{} 

def emp = new Employee() 
emp.metaClass.sayGutenAbend="Guten Abend" 

def metaclass1 = emp.metaClass.properties[1] 
emp.sayGutenAbend="Guten Nacht" 

def metaclass2 = emp.metaClass.properties[1] 

assert metaclass1 == metaclass2 // works