test suite inside spring context - spring

Is it possible to run test suite with loaded spring context, something like this
#RunWith(Suite.class)
#SuiteClasses({ Test1.class, Test2.class })
#ContextConfiguration(locations = { "classpath:context.xml" }) <------
public class SuiteTest {
}
The code above obviously wont work, but is there any way to accomplish such behavior?
This is currently how spring context is used in my test suite:
#BeforeClass
public static void setUp() {
final ConfigurableApplicationContext context =
loadContext(new String[] { "context.xml" });
jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");
// initialization of other beans...
}

I have tried you code, the test suite are running with spring context loaded. Can you explain in more detail what the problem is?
here is the code:
#RunWith(Suite.class)
#SuiteClasses({ Test1.class, Test2.class })
public class SuiteTest {
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:context.xml" })
#Transactional
public class Test1 {}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:context.xml" })
#Transactional
public class Test2 {}
If you want Suite class to have its own application context, try this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:context.xml" })
#Transactional
public class SuiteTest {
#Test public void run() {
JUnitCore.runClasses(Test1.class, Test2.class);
}
}

Related

How to inject certain properties values during junit to a specific test

My Spring Boot app has some test that are reading their properties from the application.yml that is in the test folder.
cat:
maxAge:30
maxNameSize:10
all is working fine, but I like that in certain tests, other values will be injected:
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {
Cat.class
})
#SpringBootTest
public class CatTest {
#Test
public void testX(){
//inject maxAge=90
// use maxNameSize from the application.yml
....
#Test
public void testZ(){
//inject maxNameSize=5
// use maxAge from the application.yml
....
}
Changing properties on method level is not supported by Spring at this moment.
You can use nested classes to accomplish this.
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {
Cat.class
})
#SpringBootTest
public class CatTest {
#Nested
#SpringBootTest(properties = "cat.maxAge=90")
public class NestedTestX {
#Test
void testX() {
//noop
}
}
#Nested
#SpringBootTest(properties = "cat.maxNameSize=5")
public class NestedTestZ {
#Test
void testZ() {
//noop
}
}
}

Is there a way to get event in spring (+junit) fired after all tests classes?

I use spring 5 + junit 5. And I have two classes - BarIT and FooIT.
#ExtendWith({SpringExtension.class})
#ContextConfiguration(classes = ModuleContextConfig.class)
public class FooIT {
#Test
public void foo() {
System.out.println("Foo");
}
}
#ExtendWith({SpringExtension.class})
#ContextConfiguration(classes = ModuleContextConfig.class)
public class BarIT {
#Test
public void bar() {
System.out.println("Bar");
}
}
This is my suite:
#RunWith(JUnitPlatform.class)
#ExtendWith({SpringExtension.class})
#SelectClasses({
FooIT.class,
BarIT.class
})
#IncludeClassNamePatterns(".*IT$")
public class SuiteIT {
}
I want to get event when tests in two classes have been executed, I mean event after FooIT.foo() and BarIT.bar(), however, I can't do that. I hoped to get ContextClosedEvent but it is not fired:
#Component
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ApplicationListenerBean implements ApplicationListener {
#Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("Event:" + event.toString());
}
}
And this is the output:
Event:org.springframework.context.event.ContextRefreshedEvent..
Event:org.springframework.test.context.event.PrepareTestInstanceEvent..
Event:org.springframework.test.context.event.BeforeTestMethodEvent..
Event:org.springframework.test.context.event.BeforeTestExecutionEvent..
Foo
Event:org.springframework.test.context.event.AfterTestExecutionEvent...
Event:org.springframework.test.context.event.AfterTestMethodEvent...
Event:org.springframework.test.context.event.AfterTestClassEvent...
Event:org.springframework.test.context.event.BeforeTestClassEvent...
Event:org.springframework.test.context.event.PrepareTestInstanceEvent...
Event:org.springframework.test.context.event.BeforeTestMethodEvent...
Event:org.springframework.test.context.event.BeforeTestExecutionEvent...
Bar
Event:org.springframework.test.context.event.AfterTestExecutionEvent...
Event:org.springframework.test.context.event.AfterTestMethodEvent...
Event:org.springframework.test.context.event.AfterTestClassEvent..
Could anyone say how to do it, if it is possible.

How to set and inject property Value from Test in Junit

My Service class uses a property set it application.properties
#Service
public class Service {
#Value("${my.prop}")
private String prop;
public Response doWork(String param1,String param2){
System.out.println(prop); //NULL!!!
}
}
I want to test it and set my own value:
Test Class:
#RunWith(MockitoJUnitRunner.class)
#TestPropertySource(locations = "application.properties",properties = { "my.prop=boo" })
public class ServiceUnitTest {
#InjectMocks
private Service service;
#Test
public void fooTest(){
Response re = service.doWork("boo", "foo");
}
}
But when I run the test, the value is null (not even the value that exists in application.properties).
I don't have experience with MockitoJUnitRunner, but I am able to achieve this using PowerMockRunner.
Set up the application context with a test configuration, and autowire the bean from you application context into your test class. You also shouldn't need the "locations = " bit in the #TestPropertySource annotation.
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringRunner.class)
#TestPropertySource(properties = { "my.prop=boo" })
public class ServiceUnitTest {
#TestConfiguration
static class ServiceUnitTestConfig {
#Bean
public Service service() {
return new Service();
}
}
#Autowired
Service service;
#Test
public void fooTest(){
Response re = service.doWork("boo", "foo");
}
}

prevent component scan for unit test

I have a class as following
#ComponentScan(basePackages = { "com.abc.def" })
#Configuration
public class ClassUnderTest(){
#Bean
public void createSomeBean()
{
}
}
I am unit testing this class using
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = ClassUnderTest.class)
public class someUnitTest()
{}
How do I prevent component scan from happening when creating a test context from ClassUnderTest
#ComponentScan(basePackages = "com.abc.def",
excludeFilters = {
#Filter(type = ASSIGNABLE_TYPE,
value = {
ClassUnderTest.class
})
})

Maven will not execute tests

I have a default Maven directory structure, but it will not see/run my tests. The directory structure is as followed:
src
-main
-java
-com.foo.webservice
-...
-test
-java
-com.foo.webservice
-AbstractTest.java
When I run the command mvn test, it tells me nothing, but a successful build.
The project is viewable on my Git over here.
This is my test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
public abstract class AbstractTest {
#Autowired
private CustomerDAO dao;
#Test
public void testGetCustomer() {
Customer customer = new Customer();
customer.setUsername("JUnitCustomer");
customer.setCompanyName("SpringTest");
customer.setPhoneNumber("0612345678");
if (customer != null) {
assertNotNull("Username isn't null", customer.getUsername());
assertNotNull("Company isn't null", customer.getCompanyName());
assertTrue(customer.getPhoneNumber().length() == 8);
}
}
#Test
public void testGetCustomerPhoneNumber() {
assertTrue(dao.getCustomer(0).getPhoneNumber().length() == 8);
}
}
By looking at your code, the class you want to test with JUnit is abstract.
However, for JUnit to run your test, your class must not be abstract. You should declare your class like this:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
public class MyTest {
#Test
public void testSomething() {
}
}

Resources