繁体   English   中英

内部类中的测试用例 JUnit

[英]Test cases in inner classes with JUnit

我阅读了有关结构化单元测试的信息,其中包含每个 class 的测试 class 和每个方法的内部 class。 我认为这似乎是一种组织测试的简便方法,所以我在我们的 Java 项目中尝试了它。 但是,内部类中的测试似乎根本没有被接受。

我大致是这样做的:

public class DogTests
{
    public class BarkTests
    {
        @Test
        public void quietBark_IsAtLeastAudible() { }

        @Test
        public void loudBark_ScaresAveragePerson() { }
    }

    public class EatTests
    {
        @Test
        public void normalFood_IsEaten() { }

        @Test
        public void badFood_ThrowsFit() { }
    }
}

JUnit 不支持这个,还是我做错了?

你应该用@RunWith(Enclosed.class)注释你的类,就像其他人说的那样,将内部类声明为静态:

@RunWith(Enclosed.class)
public class DogTests
  {
  public static class BarkTests
  {
    @Test
    public void quietBark_IsAtLeastAudible() { }

    @Test
    public void loudBark_ScaresAveragePerson() { }
  }

  public static class EatTests
  {
    @Test
    public void normalFood_IsEaten() { }

    @Test
    public void badFood_ThrowsFit() { }
  }
}
public class ServicesTest extends TestBase {

   public static class TestLogon{

       @Test
       public void testLogonRequest() throws Exception {
         //My Test Code
       }
   }
}

使内部类静态对我有用。

在 JUnit 5 中,您只需将非静态内部类标记为@Nested

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

public class DogTests {
    @Nested
    public class BarkTests {
        @Test
        public void quietBark_IsAtLeastAudible() { }

        @Test
        public void loudBark_ScaresAveragePerson() { }
    }

    @Nested
    public class EatTests {
        @Test
        public void normalFood_IsEaten() { }

        @Test
        public void badFood_ThrowsFit() { }
    }
}

我认为一些答案可能适用于旧版本的 JUnit。 在 JUnit 4 中,这对我有用:

    @RunWith(Suite.class)
    @Suite.SuiteClasses({ DogTests.BarkTests.class, DogTests.EatTests.class })
    public class DogTests
    {
        public static class BarkTests
        {
            @Test
            public void quietBark_IsAtLeastAudible() { }

            @Test
            public void loudBark_ScaresAveragePerson() { }
        }

        public static class EatTests
        {
            @Test
            public void normalFood_IsEaten() { }

            @Test
            public void badFood_ThrowsFit() { }
        }
    }

我也成功使用Nitor Creation 的 Nested Runner

如何使用 Nitor Creation 的 Nested Runner

有一个帖子在这里解释它

添加此依赖项:

<dependency>
    <groupId>com.nitorcreations</groupId>
    <artifactId>junit-runners</artifactId>
    <version>1.2</version>
    <scope>test</scope>
</dependency>

和一个@RunWith给你的测试:

import com.nitorcreations.junit.runners.NestedRunner
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
  
@RunWith(NestedRunner.class)
public class RepositoryUserServiceTest {
           
    public class RegisterNewUserAccount {
     
        public class WhenUserUsesSocialSignIn {
             
            public class WhenUserAccountIsFoundWithEmailAddress {
                 
                @Test
                public void shouldThrowException() {
                     assertTrue(true);
                }
            }
         
        }
    }
}

PS:示例代码取自上述博文并进行了修改

我刚刚看到这篇关于内部类测试的帖子(11 年后)。 仅当 class 首先应该是 static 时,内部 class 才能简单地转换为等效的 static 形式。 Static 内部类不是真正的内部类,因为没有包含this 它们与顶级类具有完全相同的语义(可见性限制除外)。

要测试“真实的”内部 class [取决于其封闭实例],您需要使用 Java 语言提供的接口,用于在封闭 class 的 scope 之外创建内部 class 实例。该接口在每个构造函数中包含一个额外参数这是封闭的实例。 通过这种方式,Java 编译器将一个内部 class 转换为一个特殊的顶级 class,它具有一个损坏的名称(很多 $ 符号)和增强的构造函数。 可以在源级别执行相同的转换。 原则上,可以测试这些转换后的类,但这是一个复杂的过程,因为被测试的程序已经转换了语法并且测试代码必须构造一个(模拟)object 作为封闭实例。

另一种测试真正内部类的方法是为每个方法编写一个可执行方法契约,包括一个可执行逻辑前置条件和一个可执行逻辑后置条件。 然后,可以在运行调用内部 class 方法的常规顶级测试的过程中评估这些可执行合约。

在实践中,我通常满足于在顶层测试过程中间接测试内部 class 方法。 为所有方法编写和测试可执行合约是一种更严格但更昂贵的替代方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM