JUnit 中的固定装置和文件结构

发布于 2024-09-15 08:29:33 字数 1993 浏览 3 评论 0原文

我正在构建一个纸牌游戏,该游戏仅因下面给出的示例而相关。

我认为自己是一位相当有经验的 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++ 的易用性宠坏而太容易放弃了,在其中我包含一个文件来获取其所有功能,并且我可以在一个文件中拥有一堆测试功能的类?)

I'm building a card game which is only relevant because of the examples given below.

I consider myself a fairly experienced C++ programmer, with considerable TDD experience in that language; most recently using UnitTest++. I am new to Java, and intend to target Android once I get my Java legs.

What I want to do is something akin to this UnitTest++ setup:

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.

Now, in C++ I'd just throw this all into a DeckTest.cpp file and be done; multiple fixtures all testing one client class. Makes sense to me.

However, in Java, I feel like I want to do something similar:

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?
}

...since I can only have one public class per module I figured I'd try to build a suite or something, but I can't figure out the way to do it. I'm using the various AllTests.java in the junit-4.8.2 distro to guide me, but the one that looked most promising (org.junit.tests.AllTests) gives me compile errors when I try to mimic it.

I figured the preferred way would be to have internal classes, but junit doesn't pick those up either. It feels yucky to me to have to split these out into different files, but maybe that's just the Java way?

Tips most appreciated, thanks!

Edit: Largely I'm curious about file structure. Given the lack of response, I'm starting to think that it's not particularly feasible to have all of these things in one file. So, when developing tests like this, how do people structure them in Java? Would I create a test.deck package, with a number of test classes containing only a small number of tests, or do folks just go ahead and embrace the duplication and jam them all into one test class? (Am I giving up too easily by feeling spoiled by the ease of use of UnitTest++, where I include one file to get all of its features and where I can have a bunch of classes that test a feature in one file?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

悲念泪 2024-09-22 08:29:33

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.

或者您可以将 Enclosure.class 视为替代运行程序,但您会遇到 DeckTester 的问题,因为它本身没有测试。

一般来说,比起继承更喜欢组合,因此继承固定装置而不是组合它的模式让我犹豫不决。可能没问题,但在 Java 中可能限制太多。

Java has a limitation where only one public top level class can be in a file, so the type of style you are looking for is not quite the "java" way of doing it, but if you want that style it is more natural in TestNG, so I suggest you also consider that framework.

In JUnit, what you do is have an outer class that is a holder of all of these various classes:

@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.

Or you can look the Enclosed.class as an alternative runner, but you would run into issues with the DeckTester since it has no tests itself.

In general, prefer composition over inheritance, so the pattern of inheriting the fixture rather than composing it gives me pause. It may be ok, but it may be too limiting in Java.

烛影斜 2024-09-22 08:29:33

我们可以创建一个空类,其中在注释中包含可运行的类:

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

We can create an empty class which has the runnable classes in annotation:

@RunWith(Suite.class)
@Suite.SuiteClasses({My1Test.class, My2Test.class, My2Test.class})
public class AllTests {
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文