JUnit中的夹具和文件结构

时间:2010-08-17 05:35:39

标签: java unit-testing junit

我正在建立一个只有相关的纸牌游戏,因为下面给出的例子。

我认为自己是一位经验丰富的C ++程序员,在该语言方面具有相当的TDD经验;最近使用UnitTest ++。我是Java新手,一旦得到我的Java版本,我打算将Android作为目标。

想要做的事情类似于UnitTest ++设置:

class DeckTest
{
public:
   Deck deck;
};

class EmptyDeck : public DeckTest
{
   // doesn't need to do anything for this simplified example
};

TEST_FIXTURE(EmptyDeck, HasNoCards)
{
   CHECK_EQUAL(0, deck.GetNumCards());
}

TEST_FIXTURE(EmptyDeck, ThrowsOnCardAccess)
{
   CHECK_THROWS(InvalidCardIndexException, deck.GetCard(0));
}

class DeckWithCards : public DeckTest
{
   void setUp()
   {
      // load deck with a bunch of cards
   }
};

TEST_FIXTURE(DeckWithCards, FirstCardIsAccessible)
{
   // ...etc.

现在,在C ++中,我只是把它全部放到DeckTest.cpp文件中并完成;多个灯具全部测试一个客户类。对我有意义。

然而,在Java中,我觉得我想做类似的事情:

class DeckTester {
    Deck deck = new Deck();
}

class EmptyDeck extends DeckTester {
    @Test
    public void EmptyDeckHasNoCards() {
        assertThat(deck.GetNumCards(), equalTo(0));
    }

    @Test(expected=Deck.EmptyDeckException.class)
    public void EmptyDeckThrowsWhenGettingCard() throws Deck.EmptyDeckException {
        Card card = deck.GetCard(0);
    }
}

class DeckWithCards extends DeckTester {
    @Before
    public void AddCards() {
        Card card = new Card(Card.Type.k_missed);
        deck.AddCard(card);
        // ...or similar...
    }
}

public class DeckTests {
   // What goes here?
}

...因为每个模块我只能有一个公共类,我想我会尝试构建套件或其他东西,但我无法弄清楚如何做到这一点。我在junit-4.8.2发行版中使用各种AllTests.java来指导我,但是当我试图模仿它时,看起来最有希望的那个(org.junit.tests.AllTests)会给我编译错误。

我认为首选的方法是拥有内部类,但是junit也不会选择那些。我不得不把它们拆分成不同的文件,但是这可能只是Java的方式让我感到很难过吗?

提示最感谢,谢谢!

编辑:很大程度上我对文件结构感到好奇。鉴于缺乏回应,我开始认为将所有这些东西都放在一个文件中并不是特别可行。那么,在开发这样的测试时,人们如何用Java构建它们?我是否会创建一个test.deck包,其中包含许多只包含少量测试的测试类,或者请大家继续进行复制并将它们全部插入到一个测试类中? (我是否因为使用UnitTest ++的易用性而感到轻易放弃,我在其中包含一个文件以获取其所有功能,以及我可以在一个文件中测试一个功能的一堆类?)

2 个答案:

答案 0 :(得分:1)

Java有一个限制,只有一个公共顶级类可以在一个文件中,所以你要找的样式类型并不是“java”方式,但是如果你想要这种样式它更多在TestNG中很自然,所以我建议你也考虑一下这个框架。

在JUnit中,你所做的是拥有一个外部类,它是所有这些不同类的持有者:

@RunWith(Suite.class)
@Suite.SuiteClasses({EmptyDeck.class, DeckWithCards.class})
public class AllTests {
    public static class DeckTester {
           ///etc.
    }
    public static class EmptyDeck.class extends DeckTester {
          ///etc.

或者您可以将Enclosed.class视为替代跑步者,但由于DeckTester本身没有测试,因此您会遇到问题。

一般来说,更喜欢构图而不是继承,所以继承夹具而不是组合它的模式让我停下来。它可能没问题,但在Java中它可能过于局限。

答案 1 :(得分:0)

我们可以创建一个在注释中具有runnable类的空类:

@RunWith(Suite.class)
@Suite.SuiteClasses({My1Test.class, My2Test.class, My2Test.class})
public class AllTests {
}