복붙노트

[SPRING] Spring을 사용하여 주입 된 필드에 Parameterized JUnit 테스트 러너를 사용하려면 어떻게해야합니까?

SPRING

Spring을 사용하여 주입 된 필드에 Parameterized JUnit 테스트 러너를 사용하려면 어떻게해야합니까?

나는 단위 테스트에 디렉토리 경로를 삽입하기 위해 Spring을 사용하고있다. 이 디렉토리에는 매개 변수화 된 테스트 러너를 사용하여 매개 변수화 된 테스트 케이스에 대한 테스트 데이터를 생성하는 데 사용해야하는 여러 파일이 있습니다. 불행히도, 테스트 러너는 매개 변수를 제공하는 메소드가 정적이어야한다고 요구합니다. 디렉토리가 비 정적 필드에만 삽입 될 수 있기 때문에 이것은 내 상황에서는 작동하지 않습니다. 이 문제를 어떻게 해결할 수 있을지 생각해?

해결법

  1. ==============================

    1.매개 변수화 된 테스트 러너에 대해 언급 한 이후 JUnit 4.X를 사용하고 있다고 가정합니다. 이것은 @RunWith (SpringJUnit4ClassRunner)를 사용하지 않는다는 것을 의미합니다. 문제는 아니며 제 가정을 나열하는 것입니다.

    매개 변수화 된 테스트 러너에 대해 언급 한 이후 JUnit 4.X를 사용하고 있다고 가정합니다. 이것은 @RunWith (SpringJUnit4ClassRunner)를 사용하지 않는다는 것을 의미합니다. 문제는 아니며 제 가정을 나열하는 것입니다.

    다음은 Spring을 사용하여 XML 파일에서 테스트 파일 디렉토리를 가져옵니다. 주입하지는 않지만 데이터는 여전히 테스트에 사용할 수 있습니다. 그리고 정적 인 방법에서도 그렇습니다.

    필자가 보게되는 유일한 단점은 Spring 설정이 여러 번 파싱 / 구성된다는 의미 일 수 있다는 것입니다. 필요한 경우 특정 정보를 테스트하여 더 작은 파일을로드 할 수 있습니다.

    @RunWith(Parameterized.class)
    public class MyTest {
        @Parameters
        public static Collection<Object[]> data() {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("/jeanne/jeanne.xml");
            String dir = ctx.getBean("testFilesDirectory", String.class);
    
                // write java code to link files in test directory to the array
            return Arrays.asList(new Object[][] { { 1 } });
        }
    // rest of test class
    }
    
  2. ==============================

    2.Spring의 TestContextManager를 사용할 수있다. 이 예제에서는 Parameterized 대신 Theories를 사용합니다.

    Spring의 TestContextManager를 사용할 수있다. 이 예제에서는 Parameterized 대신 Theories를 사용합니다.

    @RunWith(Theories.class)
    @ContextConfiguration(locations = "classpath:/spring-context.xml")
    public class SeleniumCase {
      @DataPoints
      public static WebDriver[] drivers() {
        return new WebDriver[] { firefoxDriver, internetExplorerDriver };
      }
    
      private TestContextManager testContextManager;
    
      @Autowired
      SomethingDao dao;
    
      private static FirefoxDriver firefoxDriver = new FirefoxDriver();
      private static InternetExplorerDriver internetExplorerDriver = new InternetExplorerDriver();
    
      @AfterClass
      public static void tearDown() {
        firefoxDriver.close();
        internetExplorerDriver.close();
      }
    
      @Before
      public void setUpStringContext() throws Exception {
        testContextManager = new TestContextManager(getClass());
        testContextManager.prepareTestInstance(this);
      }
    
      @Theory
      public void testWork(WebDriver driver) {
        assertNotNull(driver);
        assertNotNull(dao);
      }
    }
    

    나는이 해결책을 여기에서 발견했다 : 스프링으로 매개 변수화 된 / 이론 테스트를하는 방법

  3. ==============================

    3.2015 년 말 또는 그 이후에 읽는 분들을 위해 Spring 4.2에는 SpringJUnit4ClassRunner 외에 Spring TestContext Framework에 대한 지원을 활용하는 SpringClassRule과 SpringMethodRule이 추가되었습니다.

    2015 년 말 또는 그 이후에 읽는 분들을 위해 Spring 4.2에는 SpringJUnit4ClassRunner 외에 Spring TestContext Framework에 대한 지원을 활용하는 SpringClassRule과 SpringMethodRule이 추가되었습니다.

    이것은 MockitoJUnitRunner 또는 Parameterized와 같은 모든 러너에 대한 일등급 지원을 의미합니다.

    @RunWith(Parameterized.class)
    public class FibonacciTest {
        @ClassRule public static final SpringClassRule SCR = new SpringClassRule();
        @Rule public final SpringMethodRule springMethodRule = new SpringMethodRule();
    
        long input;
        long output;
    
        public FibonacciTest(long input, long output) { this.input = input; ...} 
    
        @Test
        public void testFibonacci() {
            Assert.assertEquals(output, fibonacci(input));
        }
    
        public List<Long[]> params() {
            return Arrays.asList(new Long[][] { {0, 0}, {1, 1} });
        }
    }
    
  4. ==============================

    4.@RunWith (Parameterized.class)와 @ContextConfiguration으로 테스트 클래스에 주석을 추가하는 것만으로도 충분합니다. 의존성 삽입에 @Autowired를 사용하고 초기화를 위해 생성자에서 TestContextManager를 사용합니다 (예 :

    @RunWith (Parameterized.class)와 @ContextConfiguration으로 테스트 클래스에 주석을 추가하는 것만으로도 충분합니다. 의존성 삽입에 @Autowired를 사용하고 초기화를 위해 생성자에서 TestContextManager를 사용합니다 (예 :

    @RunWith(Parameterized.class)
    @ContextConfiguration(classes = TestConfig.class)
    public class MyTest {
    
        @Autowired
        private DataSource dataSource;
    
        private final int param;
    
        @Parameterized.Parameters
        public static List<Object[]> params() {
            return Arrays.asList(new Object[][]{
                {1},
                {2},
            });
        }
    
        public MyTest(int p) {
            this.param = p;
            new TestContextManager(getClass()).prepareTestInstance(this);
        }
    
        @Test
        public void testSomething() {
           …
        }
    }
    
  5. ==============================

    5.어떤 문제없이 Parameterized.class 함께 다음 솔루션을 사용합니다. http://bmocanu.ro/coding/320/combining-junit-theoriesparameterized-tests-with-spring/

    어떤 문제없이 Parameterized.class 함께 다음 솔루션을 사용합니다. http://bmocanu.ro/coding/320/combining-junit-theoriesparameterized-tests-with-spring/

    @ContextConfiguration(value = "classpath:test-context.xml")
    public abstract class AbstractJunitTest extends AbstractJUnit4SpringContextTests {
        private static TestContextManager testContextManager = null;
        private static DAOFactory daoFactory = null;
    
        @Before
        public void initApplicationContext() throws Exception {
            if (testContextManager == null) {
                testContextManager = new TestContextManager(getClass());
                testContextManager.prepareTestInstance(this);
                daoFactory = (DAOFactory)applicationContext.getBean("daoFactory");
            }
        }
    
        protected DAOFactory getDaoFactory() throws Exception {
            return daoFactory;
        }
    }
    
    
    
    @RunWith(Parameterized.class)
    public class SomeTestClass extends AbstractJunitTest {
         ...
    }
    
  6. ==============================

    6.JUnit 4.12 매개 변수화 된 팩토리가없는 첫 번째 솔루션은 개선 된 솔루션 아래에 있습니다.

    JUnit 4.12 매개 변수화 된 팩토리가없는 첫 번째 솔루션은 개선 된 솔루션 아래에 있습니다.

    Spring이 TestContextManager 클래스를 사용하여 모든 구성 구문 분석 및 자동 연결을 수행하도록합니다.

    트릭은 가짜 테스트 인스턴스를 사용하여 자동 필드를 가져 와서 효과적으로 실행되는 매개 변수화 된 테스트에 전달하는 것입니다.

    그러나 prepareTestInstance ()는 autowiring을 수행하지만 beforeTestMethod () 및 afterTestMethod ()가 처리하는 테스트 트랜잭션 및 기타 좋은 내용은 관리하지 않습니다.

    @RunWith(Parameterized.class)
    @ContextConfiguration(locations = {"/test-context.xml", "/mvc-context.xml"})
    @WebAppConfiguration
    @ActiveProfiles("test-profile")
    public class MyTest {
    
      @Parameters
      public static Collection<Object[]> params() throws Exception {
        final MyTest fakeInstance = new MyTest();
        final TestContextManager contextManager = new TestContextManager(MyTest.class);
        contextManager.prepareTestInstance(fakeInstance);
        final WebApplicationContext context = fakeInstance.context;
    
        // Do what you need with Spring context, you can even access web resources
        final Resource[] files = context.getResources("path/files");
        final List<Object[]> params = new ArrayList<>();
        for (Resource file : files) {
          params.add(new Object[] {file, context});
        }
        return params;
      }
    
      @Parameter
      public Resource file;
      @Autowired
      @Parameter(1)
      public WebApplicationContext context;
    }
    

    그러나 autowired 필드가 많은 경우 배열 매개 변수에 수동으로 전달해야하기 때문에 단점이 나타납니다.

    JUnit 4.12에서는 매개 변수화 된 테스트와 스프링 주입을 결합 할 수있는 ParametersRunnerFactory를 소개합니다.

    public class SpringParametersRunnerFactory implements ParametersRunnerFactory {
    @Override
      public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
        final BlockJUnit4ClassRunnerWithParameters runnerWithParameters = new BlockJUnit4ClassRunnerWithParameters(test);
        return new SpringJUnit4ClassRunner(test.getTestClass().getJavaClass()) {
          @Override
          protected Object createTest() throws Exception {
            final Object testInstance = runnerWithParameters.createTest();
            getTestContextManager().prepareTestInstance(testInstance);
            return testInstance;
          }
        };
      }
    }
    

    팩토리는 이전 테스트 클래스에 추가되어 테스트 트랜잭션과 같은 전체 Spring 지원, 더티 컨텍스트 및 서블릿 테스트 재 초기화를 제공 할 수있다. 물론 가짜 테스트 인스턴스에서 자동 테스트 필드를 매개 변수화 된 테스트로 전달할 필요가 없습니다.

    @UseParametersRunnerFactory(SpringParametersRunnerFactory.class)
    @RunWith(Parameterized.class)
    @ContextConfiguration(locations = {"/test-context.xml", "/mvc-context.xml"})
    @WebAppConfiguration
    @Transactional
    @TransactionConfiguration
    public class MyTransactionalTest {
    
      @Parameters
      public static Collection<Object[]> params() throws Exception {
        final MyTransactionalTest fakeInstance = new MyTransactionalTest();
        final TestContextManager contextManager = new TestContextManager(MyTransactionalTest.class);
        contextManager.prepareTestInstance(fakeInstance);
        final WebApplicationContext context = fakeInstance.context;
    
        // Do what you need with Spring context, you can even access web resources
        final Resource[] files = context.getResources("path/files");
        final List<Object[]> params = new ArrayList<>();
        for (Resource file : files) {
          params.add(new Object[] {file});
        }
        return params;
      }
    
      @Parameter
      public Resource file;
    
      @Autowired
      private WebApplicationContext context;
    }
    
  7. ==============================

    7.Spring은 @Autowired를 사용하여 setter를 사용하여 삽입한다는 것을 기억하십시오. 따라서 @Autowired를 사용하는 대신 setter를 사용하십시오.

    Spring은 @Autowired를 사용하여 setter를 사용하여 삽입한다는 것을 기억하십시오. 따라서 @Autowired를 사용하는 대신 setter를 사용하십시오.

    private static String directory;
    
    public void setDirectory(String directory) {
        this.directory = directory;
    }
    
    public static String getDirectory() {
         return directory;
    }
    
  8. from https://stackoverflow.com/questions/3405422/how-can-i-use-the-parameterized-junit-test-runner-with-a-field-thats-injected-u by cc-by-sa and MIT license