【问题标题】:Unit tests fail when tests run as set?当测试按设置运行时单元测试失败?
【发布时间】:2023-04-04 10:38:01
【问题描述】:

Link to repo

我正在学习 Java 单元测试,并为某些算法编写了一些单元测试。

当我单独运行单元测试时,它们可以正常通过,但是当我作为一组运行它们时,只有第一个通过,其余的则失败。

例如,Test1、Test2 和 Test3 作为一个集合运行;那么Test1通过,Test2和Test3失败。

如果我注释掉 Test1 的代码,然后运行 ​​Test2 和 Test3; Test2 通过,Test3 失败。

当我单独运行它们时,它们都通过了。

算法代码

package com.kbajpai.algorithms.ds;

class Node {
    private static Node sInstance;

    static {
        try {
            sInstance = new Node();
        } catch (Exception e) {
            throw new RuntimeException("Could not create singleton instance");
        }
    }

    static Node getInstance() {
        return sInstance;
    }

    private long mData;
    private int mCount;
    private Node mLeft;
    private Node mRight;

    private Node() {
        mCount = 0;
        mLeft = null;
        mRight = null;
    }

    private Node(long data) {
        mData = data;
        mLeft = null;
        mRight = null;
        mCount = 1;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();

        if (mCount == 0) {
            return "";
        } else {
            if (mLeft != null) {
                sb.append(mLeft.toString()).append(",");
            }
            sb.append(mData).append(":").append(mCount);
            if (mRight != null) {
                sb.append(",").append(mRight.toString());
            }
        }
        return sb.toString();
    }

    private void insert(long data) {
        if (mCount == 0) {
            mData = data;
            mCount++;
        } else {
            if (data == mData) {
                mCount++;
            } else if (data > mData) {
                if (mRight != null) {
                    mRight.insert(data);
                } else {
                    mRight = new Node(data);
                }
            } else {
                if (mLeft != null) {
                    mLeft.insert(data);
                } else {
                    mLeft = new Node(data);
                }
            }
        }
    }

    String getScores(long[] data) {
        for (long aData : data) {
            insert(aData);
        }

        return toString();
    }
}

单元测试代码:

package com.kbajpai.algorithms.ds;

import com.kbajpai.datagen.ds.ScoreStatsData;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import static junit.framework.TestCase.assertTrue;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NodeTest {
    @Test
    public void test01ScoreStats_Ten() throws Exception {
        long[] data = ScoreStatsData.getInstance().getNumbers(ScoreStatsData.FILE_TEN);
        String expected = ScoreStatsData.getInstance().getStats(ScoreStatsData.FILE_TEN_STATS);

        assertTrue(expected.equals(Node.getInstance().getScores(data)));
    }

    @Test
    public void test02ScoreStats_Hundred() throws Exception {
        long[] data = ScoreStatsData.getInstance().getNumbers(ScoreStatsData.FILE_HUNDRED);
        String expected = ScoreStatsData.getInstance().getStats(ScoreStatsData.FILE_HUNDRED_STATS);

        String actual = Node.getInstance().getScores(data);
        assertTrue(expected.equals(actual));
    }

    @Test
    public void test03ScoreStats_Thousand() throws Exception {
        long[] data = ScoreStatsData.getInstance().getNumbers(ScoreStatsData.FILE_THOUSAND);
        String expected = ScoreStatsData.getInstance().getStats(ScoreStatsData.FILE_THOUSAND_STATS);

        String actual = Node.getInstance().getScores(data);
        assertTrue(expected.equals(actual));
    }

    @Test
    public void test04ScoreStats_Million() throws Exception {
        long[] data = ScoreStatsData.getInstance().getNumbers(ScoreStatsData.FILE_MILLION);
        String expected = ScoreStatsData.getInstance().getStats(ScoreStatsData.FILE_MILLION_STATS);

        String actual = Node.getInstance().getScores(data);
        assertTrue(expected.equals(actual));
    }

    @Test
    public void test05ScoreStats_TenMillion() throws Exception {
        long[] data = ScoreStatsData.getInstance().getNumbers(ScoreStatsData.FILE_TEN_MILLION);
        String expected = ScoreStatsData.getInstance().getStats(ScoreStatsData.FILE_TEN_MILLION_STATS);

        String actual = Node.getInstance().getScores(data);
        assertTrue(expected.equals(actual));
    }
}

注:

【问题讨论】:

  • 这可能是因为您到处都在使用单例。由于Node 是一个单例,因此您不会在每个测试用例中都创建一个新的,而是再次使用上一个测试中的同一个,其中当然包含您之前添加的所有条目

标签: java unit-testing intellij-idea gradle junit


【解决方案1】:

这是由于您使用具有持久状态的static 变量造成的。第一个测试运行,它将一些数据放入单例对象中,当第二个和以后的测试在同一批次中运行时,这些数据仍然存在。

要解决此问题,您需要在每次测试之间重置单例,或者重写代码以首先不使用单例模式。

【讨论】:

  • Node 从单例更改为非单例。我怀疑在 ScoreStatsData 上,从未想过 Node.
猜你喜欢
  • 2011-05-22
  • 2017-02-26
  • 2017-10-12
  • 1970-01-01
  • 2019-11-29
  • 2023-03-06
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多