2013-01-07 30 views
1

我试图执行一个对象的深层副本,然后在其中修改新对象而不改变oringial。为了测试我使用JUnit来确保功能性正常工作的功能。深度复制,JUnit测试Java

目前的测试基本上是复制游戏“质量效应3”和改变当前的配音演员。

游戏类

@Override 
protected Object clone(){ 
    Game obj = new Game(getTitle(), getLeadVoiceActor(), getRating()); 
    return obj; 
} 

JUnit测试

@Before 
public void setUp() { 
    p1 = new Person("Mark", "Meer"); 
    g1 = new Game("Mass Effect 3", p1, 5); 
} 

@Test 
public void testClone() throws CloneNotSupportedException { 
    //This works 
    Game g2 = (Game)g1.clone(); 
    assertEquals(g2, g1); 
    assertNotSame(g2, g1); 

    //This doesn't even though the lead voice actor is now different 
    p1 = g1.getLeadVoiceActor(); 
    p1.setFirstName("Jennifer"); 
    p1.setLastName("Hale"); 
    assertFalse(g2.equals(g1)); 
    assertEquals("Jennifer Hale", g1.getLeadVoiceActor().toString()); 
    assertEquals("Mark Meer", g2.getLeadVoiceActor().toString()); 
} 

试验是用junit.framework.assertionfailederror失败。

+7

这是什么问题? – MrSmith42

+0

您的克隆不是深度复制,而只是浅拷贝。做'super.clone()'会产生同样的效果。 –

+0

@ madth3我纠正了这些错别字。 JB Nizet我当时正在阅读一本书,指出我所做的确实是一个深层复制,你能否证实它是错误的? – Melky

回答

3

如果你的问题是:为什么原始游戏中的人和克隆游戏中的人是一样的?,那么答案就是你不是很深的克隆,而是很浅的克隆。

调用getLeadVoiceActor()并将结果分配给克隆的游戏将参考传递给克隆游戏的人。它不做任何复制。要进行复印,就需要

protected Object clone(){ 
    Game obj = new Game(getTitle(), (Person) getLeadVoiceActor().clone(), getRating()); 
    return obj; 
} 

protected Object clone(){ 
    Game obj = new Game(getTitle(), 
         new Person(getLeadVoiceActor().getFirstName(), getLeadVoiceActor().getLastName()), 
         getRating()); 
    return obj; 
} 

注意的是,使用clone()赞成拷贝构造函数是不鼓励。如果您实施克隆,则应使用super.clone()

另请注意,如果它是不可变的,则不需要克隆该人员。

+0

正如我的getLeadVoiceActor()不过是一个字符串。我无法按照您的建议克隆它。 – Melky

+0

它怎么可能是一个'String'?你正在调用一些方法('setFirstName','setLastName')。 –

+0

其实不理我,我很傻我刚才意识到我做了什么,谢谢JB Nizet。我完全同意赞成复制构造函数,但我希望了解深度复制实际上是如何实现的。 – Melky