How can I find out if code is running inside a JUnit test or not?

前端 未结 11 1277
梦毁少年i
梦毁少年i 2020-12-24 10:34

In my code I need to do certain fixes only when it is run inside a JUnit test. How can I find out if code is running inside a JUnit test or not? Is there something like JUni

相关标签:
11条回答
  • 2020-12-24 10:39

    this is not strictly related to the user question, but I'm pretty sure that someone that get there may find it useful.

    I use the following approach: expose a package-local constructor that will be used from tests.

    e.g.

    src/main/java/ApplicationService.java

    public class ApplicationService {
      private final Integer someInternalObject;
    
      public ApplicationService(String somePublicArgument) throws NumberFormatException {
        someInternalObject = Integer.valueOf(somePublicArgument, 16);
      }
    
      ApplicationService(Integer someInternalObject) {
         this.someInternalObject = someInternalObject;
      }
    }
    

    src/test/ApplicationServiceTest.Java

    public class ApplicationServiceTest {
      @Test
      public void testSomething() throws Exception {
        ApplicationService applicationService = new ApplicationService(0);
      }
    }
    

    expose it to all tests

    not final classes

    Extend it in the tests and provide a public constructor for the package-local or protected one.

    final classes

    Make a public Factory Method in the same package ( within tests ) that will create it using the package-local constructor.

    0 讨论(0)
  • 2020-12-24 10:41

    It might be a good idea if you want to programmatically decide which "profile" to run. Think of Spring Profiles for configuration. Inside an integration tests you might want to test against a different database.

    Here is the tested code that works

    public static boolean isJUnitTest() {  
      for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
        if (element.getClassName().startsWith("org.junit.")) {
          return true;
        }           
      }
      return false;
    }
    
    
        
    
    0 讨论(0)
  • 2020-12-24 10:44

    How about checking if the junit jar is in the classpath?

    0 讨论(0)
  • 2020-12-24 10:45

    If you're doing things differently because you're doing a unit test you're defeating the purpose of a unit test. A unit test is supposed to perform exactly like production would (except for the setup and teardown of any necessary data and such you need....but that is included in the JUnit test itself and not your code).

    However, if you truly do have a good reason for this I'd look at the stack and see if JUnit is there.

    0 讨论(0)
  • 2020-12-24 10:47

    When using Spring one can define a bean which holds this value.

    In application context:

    @Bean
    public boolean isRunningTests() {
        return false;
    }
    

    In test application context:

    @Bean
    public boolean isRunningTests() {
        return true;
    }
    

    Inject the value to a Spring component:

    @Resource
    private boolean isRunningTests;
    
    private void someMethod() {
        if (isRunningTests()) {
            ....
    
    0 讨论(0)
  • 2020-12-24 10:49

    The shortest (least code) solution is to have a global flag that is set when tests are not running. You can then set it once in your main() (or similar entry point) instead of setting it repeatedly in setup methods of all test classes. This will work as long as there is no other way to enter the code (no alternate main).

    The second shortest solution is to scan the call stack for junit package like in Janning's answer. This will work as far as junit doesn't hide itself behind another library and an executor.

    Dependency injection will work too, but in this case it's just a fancy way to set what's essentially a global flag.

    0 讨论(0)
提交回复
热议问题