SpringBoot MockMVC Controller Test with in-memory H2 not creating JPA entities as table or not inserting seed data - spring

Status returns 200 but when i checked the logs cannot see any H2 logs for creating tables or inserting data. So, what do you suggest me to do.
Another thing I want to mention is that while testing the Repository, I was able to do my Repository tests with h2 using the #DataJpaTest annotation. Below you can see my sample properties file and controllertest file.
#RunWith(SpringRunner.class)
#WebMvcTest(VehicleController.class)
#ContextConfiguration(classes=DemoApplication.class)
#AutoConfigureMockMvc
public class VehicleControllerTest {
#Autowired
private WebApplicationContext context;
#Autowired
private MockMvc mvc;
#MockBean
private VehicleService vehicleService;
#Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
#Test
public void RetrieveAllVehicles() throws Exception {
RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/vehicle").content("application/json");
MvcResult result = this.mvc.perform(requestBuilder).andExpect(status().isOk())
.andReturn();
assertEquals(12 , 12);
}
Application Properties file like that for in memory database with H2.
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.show-sql=true
spring.datasource.initialization-mode=always

Related

How to store data to MariaDB at beforeEach method in Spring boot tests?

I cannot write data to db in #beforeEach as lifecycle methods are not transactional. How can I force data to commit? Data is stored in a transaction, but it is executed after the tearDown() method. By the way, I use MariaDB test container.
#SpringBootTest
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#ContextConfiguration(initializers = TestConfigurations.Initializer.class,
classes = {Application.class, TestConfigurations.class})
#Transactional(transactionManager = "transactionManager")
public class SomeTest {
#Autowired
private SomeRepository someRepository;
#Nested
class SomeNestedClass {
#BeforeEach
void setUp() {
someRepository.saveAll(Fixtures.getSomeEntities());
}
#AfterEach
public void tearDown() {
someRepository.deleteAll();
}
...
Your test methods annotated with #Transactional will be rollback by default by Spring Test, so you can just initialize your data at the beginning of your test.
try using #BeforeTransaction
/ #AfterTransaction

How to get Hibernate Envers with Spring integration testing?

Is there some way to get Hibernate Envers to run immediately on the call to save or update instead of going at the end of the transaction ?
I have a #Transactional annotation on my (effectively end-to-end test). Since the code doesn't contain test methods I'm unable to put "flush" or whatever in it, (short of editing non-test code, which is not the desire).
I'm not sure how to get Envers log working on the calls. I need it to work as I'm using the Envers audit tables to check old entries at runtime, and would like to create test cases for this functionality.
I have the following code for unit testing :
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration("/src/webapp")
#EnableWebMvc
#Transactional
#TestPropertySource(locations= {"classpath:/config/common.properties"}, properties = {"..."})
#ContextConfiguration(locations = {"..."})
public class Test {
#Autowired
private WebApplicationContext wac;
#Autowired
private UserDetailsService detailsService;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.build();
}
...
}

Spring boot junit test #JpaDataTest not working due to missing dependency

I'm trying to write a test using my actual configuration.
In the normal spring context, I'm loading the dataSource using a #Autowired service that decrypts the database password from the properties.
It looks like this
#Configuration
public class DataBaseConfig {
#Value("${swat.datasource.url}")
private String dbURL;
#Value("${swat.datasource.driver-class-name}")
private String driverName;
#Value("${swat.datasource.username}")
private String userName;
#Value("${swat.datasource.password}")
private String hashedPassword;
#Autowired
EncryptionService encryptionService;
#Bean
public DataSource primaryDataSource() {
String password = encryptionService.decriptPassword(hashedPassword);
return DataSourceBuilder.create().url(dbURL).driverClassName(driverName).username(userName).password(password).build();
}
im now trying to run a test using #JpaDataTest (not the #SpringBootTest)
doing the following
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(replace=Replace.NONE)
#Import(DataBaseConfig.class)
#TestPropertySource(value = "file:./executor.properties")
public class NewDeviceTest {
#Autowired
NewDeviceService newDeviceService;
#Test
public void loadNewDevices() {
List<NewDevice> devices = newDeviceService.findAll();
assertEquals(1, devices.size());
assertTrue(devices.get(0).isNew());
}
}
im getting a problem since the EncryptionService in the DataBaseConfig cannot be resolved
how do i tell the Test to first load this
i tried
#ComponentScan("com.wisemon.compliance.executor.service")
but it loads all the components and some of them have a behaviour that i dont want in my test (load initial db data... scheduling etc)

CrudRepository test cases without inserting data in DB

I have one repository class which which implements CrudRepository. Then in service class I have auto wired this repositary. Then in controller class I have autowired this service.
I want to write test cases of controller Class. I am using below configuration.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class XYZControllerTest {
MockMvc mockMvc;
#Mock
private XYZController xyzController;
#Autowired
private TestRestTemplate template;
#Autowired
XYZRepository xyzRepository;
#Before
public void setup() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(xyzController).build();
}
#Test
public void testPanelShouldBeRegistered() throws Exception {
HttpEntity<Object> xyz = getHttpEntity("{\"name\": \"test 1\", \"email\": \"test10000000000001#gmail.com\","
+ " \"registrationNumber\": \"41DCT\",\"registrationDate\":\"2018-08-08T12:12:12\" }");
ResponseEntity<XYZ> response = template.postForEntity("/api/xyz", xyz, XYZ.class);
}
}
My problem is that when I run test case, data is going to insert in DB which is used for application. Can I test it without inserting data in DB.
Conceptually when we are testing services we mock repositories instead of injection.
You need to mock your repository and setup behavior for returning data.
An example :
#MockBean
XYZRepository xyzRepository;
#Test
public void test() {
// other mocks
//
when(xyzRepository.findAll()).thenReturn(Arrays.asList(new XYZ()));
// service calls
// assertions
}

Loading initial test data in H2 in spring boot

I am using Spring Boot 1.5.8.Release and writing test cases using H2 in memory database. Currently in each test case class, we have #Before annotation, where we insert data using Spring Data classes.
I want to know, can I have a single place in project where we can define data for our all test cases. The database tables are created by Hybernate using entity classes. The only desired thing is about inserting data from single place instead of from #Before in each test case class.
I tried to use data.sql containing Insert statements but with it, Spring does not generate schema objects (tables) due to which I get table not found errors. I do not want to specify Create Table statement for each table in schema.sql
application-test.yml
spring:
datasource:
url: jdbc:h2:mem:test;
driverClassName: org.h2.Driver
username: sa
password:
jpa:
database: h2
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create
naming.physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate:
show_sql: true
format_sql: false
Schema.sql
CREATE SCHEMA AB AUTHORIZATION SA;
AbcControllerTest.java
#RunWith(SpringRunner.class)
#ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
#SpringBootTest(classes = WebApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc
#ActiveProfiles("test")
public class AbcControllerTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private LeDataService leDataService;
#Before
public void setup() {
MyInfo myInfo = new MyInfo();
..............
..............
leDataService.save(myInfo);
}
#Test
public void getAbcTest() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/Abcs/1234567/12345678")
.with(SecurityMockMvcRequestPostProcessors.user("test").password("test123"))
.with(SecurityMockMvcRequestPostProcessors.csrf()))
.andExpect(status().isOk())
}
}
create new class annotated with #Component #Profile({ "dev", "test" }) and that implements CommandLineRunner then inject dependencies
Override run() method with your initial data that came with CommandLineRunner
for example
#Component
#Profile({ "dev", "test" })
setupInitialData implements CommandLineRunner {
UserService userService;
//bla bla
#Override
#Transactional
public void run(String... args) {
User user = new User;
user.setName("test");
userService.save(user);
//bla bla
}
}

Resources