SpringJUnit4ClassRunner with JUnit testsuite error - spring

I am trying to setup Junit test suite with Spring for the first time and tried with couple of changes in my classes, but no luck and ended up with this error : "junit.framework.AssertionFailedError: No tests found in Myclass"
Briefly, I have 2 test classes both are from same base class which loads Spring context as below
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration( locations =
{
"classpath:ApplicationContext.xml"
})
I tried adding those 2 test classes into a suite as below
#RunWith( SpringJUnit4ClassRunner.class )
#SuiteClasses({ OneTest.class, TwoTest.class })
public class MyTestSuite extends TestCase {
//nothing here
}
I am running this test suite from ant. But, this gives me an error saying "No tests found"
However, If I run the individual 2 test cases from ant, they work properly. Not sure why is this behaviour, I am sure missing something here. Please advice.

As mentioned in the comments, we run the TestSuite with #RunWith(Suite.class) and list all the test cases with #SuiteClasses({}). In order to not repeat the #RunWith(SpringJunit4ClassRunner.class) and #ContextConfiguration(locations = {classpath:META-INF/spring.xml}) in each test case, we create an AbstractTestCase with these annotations defined on it and extend this abstract class for all test cases. A sample can be found below:
/**
* An abstract test case with spring runner configuration, used by all test cases.
*/
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations =
{ "classpath:META-INF/spring.xml" })
public abstract class AbstractSampleTestCase
{
}
public class SampleTestOne extends AbstractSampleTestCase
{
#Resource
private SampleInterface sampleInterface;
#Test
public void test()
{
assertNotNull(sampleInterface);
}
}
public class SampleTestTwo extends AbstractSampleTestCase
{
#Resource
private SampleInterface sampleInterface;
#Test
public void test()
{
assertNotNull(sampleInterface);
}
}
#RunWith(Suite.class)
#SuiteClasses(
{ SampleTestOne.class, SampleTestTwo.class })
public class SampleTestSuite
{
}
If you don't want to have an AbstractSampleTest, then you need to repeat the spring runner annotations on each test case, until Spring comes up with a SpringJunitSuiteRunner similar to how they need to add a SpringJunitParameterizedRunner.

Related

#EnableCaching gets ignored when multiple Junit Tests are run together

I have a set of Junit test cases for a Spring Boot application which are annotated with #EnableCaching annotation. When these Junit tests are run individually it works fine. But when run together with the other Junit test classes , the #EnableCaching annotation seems to get ignored.
I'm using the #DirtiesContext annotation to clean the context after each test method. But this doesnt seem to be making any difference to the above mentioned issue.
Please let me know if #EnableCaching can be used in Junit Tests or not.
Please find below a sample code of the Junit Test class.
#EnableCaching
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#TestPropertySource(properties = { "a,b,c" })
#DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class SampleTest {
#BeforeEach
void setUpTest() {
//setup steps
}
#Test
void testCacheable(){
String result = controller.testCache();
}
}
#RestController
public class TestController {
#RequestMapping("/testCache")
#Cacheable(cacheNames="cache")
public String testCache() throws InterruptedException {
logger.info("Returning NOT from cache");
return "cache";
}
}

Spring boot #Import for loading config integration test not working

I have a simple spring boot app and i am implementing some integration test. I have 2 classes one that will hold my common configuration (Demo3ApplicationTests ) and the other one my integration test class(DumyClassTest), please find below it is empty for the time being:
#SpringBootTest(classes = Demo3Application.class)
class Demo3ApplicationTests {
#Test
void contextLoads() {
}
}
My integration test class:
#Import(value = Demo3ApplicationTests.class)
public class DumyClassTest{
#Autowired
DemoService demoService;
#Test
public void testImportConfig() {
demoService.logDummyMsg();
}
}
When I run the test testImportConfig the demoService value is null as I guess the #import i am not setting it up correctly. However when I extends that is DumyClassTest extends Demo3ApplicationTests the demoService is not null and the test is run correctly.
Any idea why when I use the import annotation the demoService is null?
Thanks in advance.

Run a JUnit Test with multiple Spring contexts in different projects

I have a generic code base that I need to test with different implementations and runtime configurations. Think services with multiple DAO implementations. I have generic unit tests which test the Dao interface (need the Dao autowired), and I want to invoke these from different projects.
Essentially I want something like this.
In the shared, generic project my tests will live.
So essentially, in shared project I have my tests, for example.
public class ApiTest {
#Autowired
DaoBase myDao;
#Test
public void testSomething(){
}
}
Then in the other project(s) that implement the Dao, I would have:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = { ImplementationConfigA.class })
public class ImplemtationTesterA {
//somehow invoke ApiTest.class?
}
.
#Configuration
public class ImplementationConfigA{
#Bean
DaoBase daoBase {
return new DaoImplementationGraphDB();
}
}
Again, there are multiple projects that implement the DAO layer in different ways, and I want to share the generic tests.
If I could combine #RunWith(SpringJUnit4ClassRunner.class) and #RunWith(Suite.class), it would be exactly what I desire, but that doesn't seem possible. i.e. this would be effectively what I want, which is not possible:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = { ImplementationConfigA.class })
#RunWith(Suite.class)
#Suite.SuiteClasses({ ApiTest.class })
public class ImplemtationTesterA {
...
There's got to be a trick to get something like this working.. Any ideas? Thanks!
Use profiles
#Configuration
#Profile("profileA")
public class ImplementationConfigA{
#Bean
DaoBase daoBase {
return new DaoImplementationGraphDB();
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = { ImplementationConfigA.class })
#RunWith(Suite.class)
#Suite.SuiteClasses({ ApiTest.class })
#ActiveProfiles("profileA");
public class ImplemtationTesterA {
...
Just to update:
I ended placing all the shared tests is one project, and then in each DAO implementation project creating a "dummy" test class that extended each shared test class. Not as convenient as defining a suite since each test class had to be duplicated in each implementation project, but it works.
So in the original example, the only change necessary was to make ImplemtationTesterA extend ApiTest.

Spring junit error single matching bean but found 2

I have a test class, and have created a java config class to use with this class.. But im having issues as other tests seem to throw up found two instances of bean in configuration...
my test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=TestConfiguration.class)
public class ListenerTest {
// various tests.. just basic stuff..
}
#Configuration
public class TestConfiguration {
#Bean
public MyListsner ListenerImpl() {
return Mockito.mock(MyListsner .class);
}
}
Now for this test class passes fine when i use a mock as above. My other test classes seem to fail and they are as follows:
test class which fails...
This class throws the error
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=GeneratorTestConfiguration.class)
#Transactional
public class GeneratorTest {
// various tests
}
Main config
#Configuration
#Import({
BaseConfiguration.class,
CoreBaseConfiguration.class
})
#Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
#EnableTransactionManagement(proxyTargetClass = true)
#EnableJpaRepositories(basePackages={
"com.persistence.repository"
})
#ComponentScan({ // where the components are
"com.tests"
})
public class GeneratorTestConfiguration {
}
I dont know why, when i add listener mock to the above class ListenerTest, the toher tests fail, as im being specific in those classes to use the relevant configuration when autowiring.
Seems the bean was defined twice.

Spring 3+ How to create a TestSuite when JUnit is not recognizing it

I'm using Spring 3.0.4 and JUnit 4.5. My test classes currently uses Spring's annotation test support with the following syntax:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration (locations = { "classpath:configTest.xml" })
#TransactionConfiguration (transactionManager = "txManager", defaultRollback = true)
#Transactional
public class MyAppTest extends TestCase
{
#Autowired
#Qualifier("myAppDAO")
private IAppDao appDAO;
...
}
I don't really need the line extends TestCase to run this test. It's not needed when running this test class by itself. I had to add extends TestCase so that I can add it in a TestSuite class:
public static Test suite() {
TestSuite suite = new TestSuite("Test for app.dao");
//$JUnit-BEGIN$
suite.addTestSuite(MyAppTest.class);
...
If I omit the extends TestCase, my Test Suite will not run. Eclipse will flag suite.addTestSuite(MyAppTest.class) as error.
How do I add a Spring 3+ test class to a Test Suite? I'm sure there's a better way. I've GOOGLED and read the docs. If you don't believe me, I'm willing to send you all my bookmarks as proof. But in any case, I would prefer a constructive answer. Thanks a lot.
You are right; JUnit4-style tests should not extend junit.framework.TestCase
You can include a JUnit4 test as part of a JUnit3 suite this way:
public static Test suite() {
return new JUnit4TestAdapter(MyAppTest.class);
}
Usually you would add this method to the MyAppTest class. You could then add this test to your larger suite:
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("AllTests");
suite.addTest(MyAppTest.suite());
...
return suite;
}
}
You can create a JUnit4-style suite by creating a class annotated with Suite
#RunWith(Suite.class)
#SuiteClasses( { AccountTest.class, MyAppTest.class })
public class SpringTests {}
Note that AccountTest could be a JUnit4-style test or a JUnit3-style test.

Resources