`
jlj008
  • 浏览: 95461 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Adapting Spring's JUnit 3.x base classes toJUnit 4

阅读更多

I’ve recently switched from using JUnit 3.x to JUnit 4 for most new unit tests I write. One area that causes trouble is the use of JUnit 3.x based test base classes. Spring has a tree of helper classes based on junit.framework.TestCase that make writing tests that use an ApplicationContext, dependency injection or transactions easier. These base classes can autowire your test so that your member variables are initialized and ready to go, pointing to beans managed by Spring.

I wanted the functionality provided by these base classes but wanted to continue to write tests in the JUnit4 style. The two best features of JUnit 4 are the @BeforeClass/@AfterClass annotations and the ability to have multiple setUp and tearDown methods using @Before and @After . Switching back to JUnit 3 just to use the base class seemed unfortunate.

My first attempt was to extend my JUnit 4 test from Spring’s class, AbstractDependencyInjectionSpringContextTests . When JUnit runs, it inspects your class through reflection and decides if it’s a JUnit 3 or 4 class. It sees that since Spring’s class derives from junit.framework.TestCase and so runs it as a JUnit 3 test using org.junit.internal.runners.OldTestClassRunner .

You can circumvent JUnit’s decision about this test and force it to be run as a JUnit 4 test instead using the annotation RunWith((TestClassRunner.class) . This forces JUnit to use the new test runner (TestClassRunner) even though the class derives from TestCase . I created a class called SpringManagedTests that derives from AbstractDependencyInjectionSpringContextTests and is annotated with RunWith . (My tests will extend SpringManagedTests ).

Next, JUnit 4 only cares about annotations and won’t run the old setUp and tearDown methods defined by the Spring classes. To get around this, add methods with Before and After annotations to call setUp and tearDown.

@Before final









 public









 void




 callSetup









()




 throws









 Exception {





  super









.




setUp









();





}






@After public









 void




 callTearDown









()




 throws









 Exception {





  super









.




tearDown









();





}










All features of the base class are now available, and JUnit 4 annotated test methods run as you would expect. The final test base class is below. To use it, derive your test from SpringManagedTests and read the docs on AbstractDependencyInjectionSpringContextTests for information on having Spring wire members of your class. In my case I use field injection – I have member variables declared as protected with the field name matching the bean name. When the test runs the field are populated.

This technique could be used for other JUnit 3 based test frameworks as well. It’s not as clean as having a pure JUnit 4 implementation but works well until that happens.

import









 org.




junit.




After;





import









 org.




junit.




Before;





import









 org.




junit.




internal.




runners.




TestClassRunner;





import









 org.




junit.




runner.




RunWith;





import









 org.




springframework.




test.




AbstractDependencyInjectionSpringContextTests;






/**










 * A base class for tests that load a spring application context










 * and use dependency injection to populate fields in the test class.










 * Unlike AbstractDependencyInjectionSpringContextTests, this










 * class can be used as a base class for JUnit 4 tests.










 * 









@author




 dyoung










 */










// RunWith is required to force what would otherwise look like a JUnit 3.x test










// to run with the JUnit 4 test runner.










@RunWith









(




TestClassRunner.




class









)





public









 class









 SpringManagedTests extends









 AbstractDependencyInjectionSpringContextTests {






    // pass through to the junit 3 calls, which are not annotated










    @Before final









 public









 void




 callSetup









()




 throws









 Exception {





        super









.




setUp









();





    }






    @After public









 void




 callTearDown









()




 throws









 Exception {





        super









.




tearDown









();





    }





}









From : http://dmy999.com/article/21/adapting-a-springs-junit-3x-base-classes-to-junit-4









分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics