Cannot read properties when used MockWebServer - testing

Hi I am new to the Junit Testing and am trying to test the third party call, for that I have used MockWebServer from okhttp3, the mockWebServer does the job of giving me a proper mocked response but in the class that I am trying to test has the following
#Autowired
Environment env
....
...
..
String url = env.getProperty(shop.url);
The above is significant as it gets the url from application.yml
But the env is null whenever I am running that particular test method which uses MockWebServer
Main Class
Class ConnectionService {
#Autowired
Environment environment;
public ConnectionService(WebClient.Builder builder) {
this.webClient = builder.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.baseUrl(usersBaseUrl).build();
}
public void getShops(){
...
..
String url = env.getProperty(shop.url);
..
..
}
Test Class
#ExtendWith(SpringExtension.class)
#SpringBootTest
#AutoConfigureWireMock(port = 0)
class ConnectionServiceTest {
public static MockWebServer mockWebServer;
private static ConnectionService connectionService;
#BeforeAll
public static void setUp() throws IOException {
mockWebServer = new MockWebServer();
connectionService = new ConnectionService(WebClient.builder(),
mockWebServer.url("/").toString();
}
#AfterAll
static void tearDown() throws IOException {
mockWebServer.shutdown();
}
#Test
void testMethod() {
MockResponse mockResponse = new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.setBody("{\"status\":\"up\",\"details\":\"details\"}")
.throttleBody(16, 5, TimeUnit.SECONDS);
mockWebServer.enqueue(mockResponse);
connectionService.getShops();
}
}
Could someone please help me out figure what am I doing wrong, is it the MockWebServer that is causing environment to be null ? even the other properties in other files are null. Thanks in advance :)
I tried to test the WebClient by making use of MockWebServer, although it worked but now I cannot read any properties either from application.yml or otherProperties.properties as the environments variables are not getting injected

Related

Junit5 Contorller Test with SpringbootTest can’t load method getParameterName()

version:spring-boot-starter-test 2.2.12.RELEASE
When I run junit5 test,I want test controller。
there is code
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = RuoYiApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc
public abstract class BaseTest {
#SpyBean
TokenService mockTokenService;
#Autowired
public MockMvc mockMvc;
#Autowired
public TestRestTemplate restTemplate;
public class CommonControllerTest extends BaseTest {
#SpyBean
CommonController commonController;
#Autowired
private MockMvc mockMvc;
#Test
public void testFileDownloadNotExists() throws URISyntaxException {
String fileName = "...";
URI uri = UriComponentsBuilder
.fromUriString("/common/download")
.queryParam("fileName", fileName)
.build()
.encode()
.toUri();
RequestEntity<Void> downloadRequest = RequestEntity
.get(uri).accept(MediaType.APPLICATION_JSON).build();
ResponseEntity<String> response = restTemplate.getForEntity(downloadRequest.getUrl(), String.class);
assertThat(response.getBody()).isEqualTo(null);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
When the request send to controller,It can't get method ParameterNames,it alos run inspectClass function read class information,but without ParameterNames and The program enter the breakpoint inspectClass read nothing becase of wrong path(com/**/CommonController$MockitoMock$1821216982.class).
It normal when I run SpringBoot Application,it can enter the breakpoint inspectClass read class inputstream。
How solve this problem?
when I change the mockito version from 3.1.0 to 3.6.28 this com/**/CommonController$MockitoMock$1821216982.class changed to
com.ruoyi.web.controller.common.CommonController

java.lang.NullPointerException: null on AutoWiring a bean in StandAlone App

When trying to use #AutoWire feature with one of StandAlone Application unable to do so instead getting Null Pointer Exception. Please highlight my mistakes if any. Your help is appreciated.
Spring Ver 5.1.5.RELEASE and we're not using any xml config file to tell spring there are annotated classes to look into instead using #ComponentScan or #EnableAutoConfiguration at the top of AppConfig and boost strap the Context from main() class as a first line. But Autowiring works perfectly with internal bean/java classes of jdk(Environment) but not with custom POJO classes. If we're trying to get through getBean method then it works. But I'm trying to avoid creating context everywhere and using getBean() Please Refer below and help me only with your valuable guidelines.
public class ContextMaster {
private static AnnotationConfigApplicationContext appContext;
public static AnnotationConfigApplicationContext getApplicationContext() {
if (appContext == null) {
appContext = new AnnotationConfigApplicationContext(ContextConfig.class);
//appContext = new AnnotationConfigApplicationContext("com.xx.xx.xxx","xx.xxx.xxxx.xxx.datamanager");
logger.debug("Context Invoked !!");
}
return appContext;
}
}
#Configuration
#EnableAutoConfiguration
#PropertySource("classpath:db.properties")
#EnableTransactionManagement
#ComponentScans(value = {
#ComponentScan(basePackages = "xxxxx.datamanager"),
#ComponentScan(basePackages = "com.xx.xx.xxx"),
#ComponentScan(basePackages = "com.xx.xx.xxx.utils")})
public class AppConfig {
#Autowired
private Environment env;
#Bean
public DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
//LocalSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
factoryBean.setDataSource(getDataSource());
Properties props=new Properties();
props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
props.put("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class"));
factoryBean.setHibernateProperties(props);
factoryBean.setAnnotatedClasses(xx.class, xxxx.class, xxxx.class, xxx.class);
return factoryBean;
}
#Bean
public HibernateTransactionManager getTransactionManager() {
return transactionManager;
}
}
// Here is NPE thrown when tried with auto-configured bean
#Component
public class Good extends Good11 {
#Autowired
private RxxxDyyyyHelper rdh;
//RxxxDyyyyHelper rdh =
ContextHelper.getApplicationContext().getBean(RxxxDyyyyHelper .class);
rdh.setProperty(); // NPE here
rdh.getProperty(); // NPE
}
// Here we're trying to initiate the LosUtils class
public class LosUtils {
public static void main(String args[]) throws Exception {
AnnotationConfigApplicationContext applicationContext = `ContextHelper.getApplicationContext();`
}
It seems like you didn't put the full code here, because your Good class won't compile this way..

JUnit to retrieve value from database to test criteria

How do I write JUnit with actual service/repository call to retrieve data from a database table instead of using a mock service/repository?
Here the below code returns an empty list of object, whereas I am expecting few hundred objects. findAll() is a simple method for which I am trying to write JUnit but later on I will be writing JUnit for a method which takes Map as JSON from request parameters and forms a criteria API so in this case, I would like to test
Request
Parsing of the request in Controller(what controller receives)
And forming the SQL Criteria and returned object and that's the reason I don't want to mock service/repository.
I am using Spring Boot Rest Controller and for Unit Testing, I am using Mocikito and JUnit.
#ActiveProfiles("test")
#RunWith(SpringRunner.class)
#WebMvcTest(CaDetailController.class)
public class CaDetailControllerTest {
private static ObjectMapper objectMapper = null;
private List<CaDetail> caDetails;
#Autowired
private MockMvc controller;
#MockBean
CaDetailRepository repository;
#BeforeClass
public static void beforeClass() {
objectMapper = new ObjectMapper();
}
#Before
public void before() {
caDetails = new ArrayList<CaDetail>();
}
#After
public void after() {
caDetails = new ArrayList<CaDetail>();
}
#AfterClass
public static void afterClass() {
objectMapper = null;
}
#Test
public void getCorporateActions() throws Exception {
MvcResult result = controller.perform(MockMvcRequestBuilders.get("/api/ca").accept(MediaType.APPLICATION_JSON)).andReturn();
caDetails = objectMapper.readValue(result.getResponse().getContentAsByteArray(), new TypeReference<List<CaDetail>>() {
});
System.out.println(">>>>>>>>>>>>>>> caDetails : " + caDetails);
assertNotNull(caDetails);
assertTrue(caDetails.size() > 0);
}
You need to write integration test for your services which will directly communicate with database. For example go through this link.
http://www.springboottutorial.com/integration-testing-for-spring-boot-rest-services

how to pass parameters to a test case while running it using Junit Suite

I want to run multitple Junit tests i have created in a package. Every test needs region and server paramter to load the correct data files. I am using System.getProperty to fetch region and serverdetails for all junit tests. I am not sure how to pass these parameters in a TestSuite Runner. Here is the test case i have created
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExpenseTests {
private static String server = System.getProperty("server");
private static String region = System.getProperty("region");
#BeforeClass
public static void setup() throws Exception {
SetUp setUp = new SetUp(region, server);
Login(region, server);
CreateClient(region, server);
}
#Test
public void test1_checkexpense() {
// code here
}
#Test
public void test2_addbasicExpense() {
//code here
}
#AfterClass
public static void teardown() throws Exception {
quit(webpage);
}
}
Here is the TestSuite
#RunWith(Suite.class)
#Suite.SuiteClasses({
ExpenseTests.class
AnotherTest.class
})
public class SmokeTestSuite {
}
I can run ExpenseTest using mvn install -Dtest="ExpenseTests" -Dserver="prod" -Dregion="us" but how do i pass region and server details in above SmokeTestSuite?
I think you may use Global variable to pass parameter to all test cases.
Example
public static String server = System.getProperty("server");
public static String region = System.getProperty("region");
Then pass it to all test cases.

Mockito Liferay service testing

I try testing my LocalServiceUtil classes, generated by service builder, with PowerMock but always getting 'null' or '0' from Util's methods.
Test class
#RunWith(PowerMockRunner.class)
#PrepareForTest(EntityLocalServiceUtil.class)
public class EntityTest {
#Test
public void testGetAnswer() throws PortalException, SystemException {
PowerMockito.mockStatic(EntityLocalServiceUtil.class);
assertEquals("hello", EntityLocalServiceUtil.getHello());
}
}
Util class contains
public static java.lang.String getHello() {
return getService().getHello();
}
and this service working correctly on deployed portlet. What i do wrong?
You have forgot to mock the methode:
#Test
public void testGetAnswer() throws PortalException, SystemException {
PowerMockito.mockStatic(EntityLocalServiceUtil.class);
when(EntityLocalServiceUtil.getHello()).thenReturn("hello"); // <- here
assertEquals("hello", EntityLocalServiceUtil.getHello());
}