Java JUnit测试对象的静态计数器

Java JUnit测试对象的静态计数器,java,unit-testing,junit,Java,Unit Testing,Junit,我是一个单元测试的初学者,我遇到了一些我不知道如何解决的失败。我试图测试我的简单类Employee,其中我有创建对象的静态计数器,因此新员工可以获得连续数字和默认名称,如“Name1”、“Name2”等。下面是我的默认initiaiton块: { currentNr = ++count; setName("Name"+currentNr); setSurname("Surname"+currentNr); } 我用很少的方法编写了一个JUnit类。它们工

我是一个单元测试的初学者,我遇到了一些我不知道如何解决的失败。我试图测试我的简单类Employee,其中我有创建对象的静态计数器,因此新员工可以获得连续数字和默认名称,如“Name1”、“Name2”等。下面是我的默认initiaiton块:

    {
    currentNr = ++count;
    setName("Name"+currentNr);
    setSurname("Surname"+currentNr);    
}
我用很少的方法编写了一个JUnit类。它们工作得很好,但有关计数器的方法只有在我单独运行它们时才起作用(当我将它们保存为单独的测试时,它们也起作用,但有这么多文件似乎很混乱)。 当我用所有的测试方法运行这个类时,计数器添加了更多的对象,我不知道为什么/When/where as测试是独立的。在测试方法中,我创建一个对象并使用assertEqual检查计数器。寻找解决方案,我尝试与@Before、@After等一起工作,但都是一样的,或者我不知道如何正确使用它。 我的问题是如何让所有的测试方法都能工作,或者在@Before方法中应该写些什么(我尝试向ArrayList添加和删除对象和/或设置为null)。我想只有在单独运行时才让测试工作是不可接受的。
任何帮助都将不胜感激。谢谢

不要使用静态字段作为员工计数器。改为使用实例字段:

public class Manager {
    private int employeesCount;

    public Employee addEmployee() {
        employeesCount++;
        Employee employee = new Employee();
        employee.setName("John " + employeesCount);
        employee.setLastName("Smith " + employeesCount);
        return employee;
    }
}
不使用静态字段(读:)来维护状态有很多很好的理由,其中一个原因是这会使代码不可测试。若您在对象中维护您的状态(在实例字段中),那个么实例化您的对象并按原样测试它并没有问题

相反,请确保您的程序中只有一个Manager实例,并且每个人都使用它(这称为singleton)。嗯,这里有一个单件模式。还有很多不使用它的好理由。因此,当您编写真正的应用程序时,您通常会使用一些依赖注入框架(如or),它们能够在您需要时为您实例化singleton


嗯,这里有点幽默,但我相信你会明白,全球状态被认为是拙劣的实践,而测试它是它如何表现出来的一种方式。frenzykryger的回答提供了很多有价值的见解,但还有更多的东西

你应该时刻牢记你的工作。在您的示例中,“单一责任原则”可以指导您找到更好的解决方案。你看,好的OO编程是关于创建有用的抽象。而你放在Employee中的一些抽象概念根本不属于这里

例如,可以创建一个类Employee来模拟为某个公司工作的人。员工是人,所以他们可能有名字;因为他们是一个组织的一部分,是的,他们可能有一个ID

但是:一个员工得到了一个分配的ID!当你在一家新公司开始工作时,人们不会走过来问你:“请告诉我们你的新数字ID”。相反,有人来告诉你“这是你的数字ID,别忘了”

因此,考虑到这一点,一些人建议:

  • 员工没有核心属性的设置者。因此,像“ID”或“name”这样的属性如果不是要更改的,应该作为参数传递给构造函数。您只需不创建employee对象,就可以在以后更改该实体的名称或id
  • 因此,正如另一个答案正确指出的那样:一些外部类,如“经理”,必须跟踪所有“已知”员工;如果添加了一个新的ID,管理器会以某种方式计算一个新的唯一ID

  • 最后:是真的:静态是良好OO设计中的一种异常。人们应该有很好的理由转向静态字段(除了常数)和方法静态总是导致代码紧密耦合——这是必须避免的

    你能发布源代码吗,也就是说,类Employee和单元测试?测试有些独立,但是一个静态字段将在两次测试之间继续存在并保持其值。也许在您的测试中,您希望在开始和结束时读取计数器的值,然后减去并测试其差值是否与预期值相同?我使用静态变量的原因是,我在讲座中使用了与计数器类似的示例,以便我们可以在没有创建任何对象(遗憾的是,没有关于测试的内容)。只是出于好奇-所以没有“漂亮”的方法来删除对象并重置计数器?您可以添加一些静态方法来重置测试计数器,但这在从多个线程运行测试时不起作用(但如果您按顺序运行测试,则会起作用)。可能会有更不漂亮的方法,包括类装入器和类重新装入。所以我的简短回答是,没有什么好办法可以做到这一点。非常感谢!同样对于其他相关主题,我现在看到了问题所在。