【问题标题】:How can I make JUnit let me set variables in one test case and access them in other if they are in the same class如何让 JUnit 让我在一个测试用例中设置变量并在另一个测试用例中访问它们(如果它们在同一个类中)
【发布时间】:2018-01-30 13:32:09
【问题描述】:

假设我有一个名为 MyTest 的测试类。

其中我有三个测试。

public class MyTest {

AnObject object;

@Before
public void setup(){
  object = new AnObject();
  object.setSomeValue(aValue);
}

@Test
public void testMyFirstMethod(){
    object.setAnotherValue(anotherValue);
    // do some assertion to test that the functionality works
    assertSomething(sometest);
}

@Test
public void testMySecondMethod(){
    AValue val = object.getAnotherValue();
    object.doSomethingElse(val);
    // do some assertion to test that the functionality works
    assertSomething(sometest);
}

有什么方法可以在第二个测试中使用anotherValue 的值,它是在第一个测试中使用其设置器设置的。我正在使用它来测试数据库功能。当我在数据库中创建一个对象时,我想获取它的 GUID,这样我就可以在以后的测试方法中使用它来进行更新和删除,而不必对 GUID 进行硬编码,从而使其与将来的使用无关。

【问题讨论】:

    标签: junit


    【解决方案1】:

    您正在两个测试之间引入依赖关系。 JUnit 故意不支持测试之间的依赖关系,你无法保证执行的顺序(测试套件中的测试类除外,见我对Has JUnit4 begun supporting ordering of test? Is it intentional? 的回答)。所以你真的想在两个测试方法之间有依赖关系:

    1. 您必须使用中间静态值
    2. 正如 Cedric 建议的那样,使用 TestNG,它专门支持依赖项
    3. 在这种情况下,您可以创建一个方法来创建线条,并从两个方法中调用它。

    我个人更喜欢 3,因为:

    1. 我得到了独立的测试,我可以只运行第二个测试(在 Eclipse 等中)
    2. 在课堂上的拆解中,我可以从数据库中删除行,即清理。这意味着无论我运行哪个测试,我总是从相同的(已知的)数据库状态开始。

    但是,如果您的设置非常昂贵,您可以将其视为集成测试并接受依赖项,以节省时间。

    【讨论】:

    • 嗯……我应该更经常地使用拆解!
    【解决方案2】:

    如果你需要这个,你应该使用TestNG(我同意它在集成测试中相当普遍)。 TestNG 使用相同的实例来运行您的测试,因此存储在字段中的值会在测试之间保留,这在您的对象创建成本很高时非常有用(JUnit 强制您使用静态来实现相同的效果,应该避免这种情况)。

    【讨论】:

    • 谢谢,我最近从 TestNG 转到了 JUnit(虽然显然不是专家),所以这将是一个简单的举动。
    【解决方案3】:

    首先,确保您的 @Test 以某种定义的顺序运行 即@FixMethodOrder(MethodSorters.NAME_ASCENDING) 在下面的示例中,我假设 test2 将在 test1 之后运行 要在它们之间共享变量,请使用 ThreadLocal(来自 java.lang)。 注意 ThreadLocal 变量的作用域是线程,所以如果你运行多个线程,每个线程都会有一个'email'的副本(在这种情况下,静态意味着它对线程唯一的全局)

    private static ThreadLocal<String> email = new ThreadLocal<String>();
    @Test
    public void test1 {
        email.set("hchan@apache.org);
    }
    
    @Test
    public void test2 {
       System.out.println(email.get());
    }
    

    【讨论】:

      【解决方案4】:

      你不应该那样做。测试应该能够以随机顺序运行。如果你想测试依赖于数据库中某个值的东西,你可以在 @Before 代码中进行,这样就不会对每个测试用例都重复。

      【讨论】:

      • 我明白你在说什么。但我认为这是不正确的一种情况。因为我必须将可能未经测试的功能放入 @Before 代码中。
      • 然后创建一个函数在所有测试开始时调用。你不想这样做,所以你不能并行运行测试。
      • 保持状态与并行运行测试并不相互排斥,看看 TestNG 是如何做到的(以及我的回答)。
      • 感谢您的跟进,我喜欢将代码放在单独的方法中的想法。
      【解决方案5】:

      我找到了很好的解决方案,只需在之前的测试中添加 Before 注释!

      private static String email = null;
      @Before
      @Test
      public void test1 {
          email = "test@google.com"
      }
      
      @Test
      public void test2 {
         System.out.println(email);
      }
      

      【讨论】:

      • 当同一个类中已经有一个用@Before注解的方法时,这将不起作用。
      • 你总是可以做到的,至少它仍然是一个解决方案。
      • 这对我有用,但对于 JUnit5,您必须使用:@BeforeTestMethod
      【解决方案6】:

      如果你和我一样,用谷歌搜索到这里但没有为你提供答案,我会留下这个:使用@BeforeEach

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多