【问题标题】:Why does my custom member variable of a class not update in other classes?为什么我的一个类的自定义成员变量没有在其他类中更新?
【发布时间】:2017-09-02 19:46:31
【问题描述】:

所以我正在做一个项目,我需要设计一个有玩家的游戏。在 Game 对象中,我初始化了一个玩家并为此玩家设置了一个 getter:

玩家只知道自己的定居点。每当我找到一个新的定居点时,该定居点都应该添加到该特定玩家的定居点数组列表中。因此,在玩家类中,我初始化了一个定居点数组列表,以及一个将定居点添加到该数组列表的方法。

当我为多个找到的结算调用编写测试时,我添加的结算不会在我的游戏对象内部的函数调用之外持续存在:

我知道这是某种范围界定或静态声明错误,但我不明白为什么我的实现不起作用。非常感谢任何帮助!

编辑:这可能是一个更好的例子,说明什么没有通过。

map.foundNewSettlement(new Coordinate(1,1));
map.foundNewSettlement(new Coordinate(-2,3));
System.out.print(map.getPlayer().getSettlements().size());

打印出来的尺寸是0,而应该是2

【问题讨论】:

  • 请不要将文本/代码作为图片发布。

标签: java oop arraylist scope static


【解决方案1】:

实例字段在每次启动测试方法时重新初始化。
所以game 实例在测试方法之间不是持久的。

如果第二个测试是测试“添加第二个结算”是否有效,您应该先添加一个结算(即创建测试的初始上下文),然后再调用该方法进行测试:addSettlement()

此外,一个测试方法不应依赖于另一个测试方法先前执行的副作用。
保持您的测试方法独立,以保持其隔离和可维护性。

因此,您应该为每个测试方法创建初始化上下文。
一开始,您可以直接在测试方法中执行此任务。
稍后如果您开始重复初始化上下文,您可以引入私有方法来执行此操作。

这是一个非常简单的示例,展示了如何使用 JUnit 创建上下文:

private Game game;

// executed before each test method
@Before
public void setup(){
    Game game = new Game();
    game.addPlayer(new Player(...));
}

@Test
public void addASecondSettlement(){
    // context
    game.getPlayer().addSettlement(new Settlement(1));
    // action
    game.getPlayer().addSettlement(new Settlement(2));
    //assertion
    Assert.assertEquals(2, game.findLastSetllement().getId());
}

【讨论】:

  • 我已将测试添加为我的程序中不同代码的示例,称为“找到的结算”,它在游戏中作为自己的功能存在。在调用我的“找到的定居点”函数后,玩家的定居点数组应该包含新的定居点,但它不会持久存在。我已将测试代码更改为我对找到的解决方案的实现。
  • 因为game实例在第一次测试后没有持久化,并且结算的ArrayList包含在game中。测试执行的更改不会在两个测试之间保留。
  • 你说得对,我在编写这些模拟测试时应该更加小心,但请考虑一下:我有一个“建立”多个解决方案的验收测试。在这一次验收测试中,定居点的建立并没有持续下去。
  • 我更新了一个示例,以展示在这种情况下如何创建上下文。
  • 感谢您迄今为止的所有帮助。我将编辑我的帖子以显示另一个未通过的测试
【解决方案2】:

除了@davidxx 回答:

您可以在测试中使用静态游戏变量:

private static Game game = new Game();

或者,如果您需要提前执行更多操作,请使用 static

    private static Game game;
    static
    {
       game = new Game();
       ... do more preparations ... 
    }

或更正确的 JUnit 方法来拥有 @BeforeClass 带注释的静态方法

private static Game game;

@BeforeClass
public static void init()
{
    game=new Game();
    ... do more preparations ... 
}

【讨论】: