Tuesday, October 13, 2015

spring boot, mockito, spring rest, junit

This is sample code to do junit test for spring rest/spring boot with mockito.

package com.demo.app.web.api.v1;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.demo.app.WebApplication;
import com.demo.app.repository.entity.Stock;
import com.demo.app.service.StockService;
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = { WebApplication.class })
public class StockControllerTest {

private static final MediaType APP_ContentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

private MockMvc mvc;

@Mock
private StockService stockService;

@InjectMocks
private StockController controller;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.standaloneSetup(controller).build();
}

@After
public void tearDown() throws Exception {
}

@Test
public void testStocks() throws Throwable {

// prepare test data
List<Stock> stocks = new ArrayList<Stock>();
// stock1
Stock stock1 = new Stock();
stock1.setStockCode("code 1");
stock1.setStockName("name 1");
stock1.setStockPrice(1.111);
stock1.setStockPriceChange(-0.111);
stocks.add(stock1);
// stock2
Stock stock2 = new Stock();
stock2.setStockCode("code 2");
stock2.setStockName("name 2");
stock2.setStockPrice(2.222);
stock2.setStockPriceChange(-0.222);
stocks.add(stock2);
// stock3
Stock stock3 = new Stock();
stock3.setStockCode("code 3");
stock3.setStockName("name 3");
stock3.setStockPrice(3.333);
stock3.setStockPriceChange(-0.333);
stocks.add(stock3);

Mockito.when(stockService.findAll()).thenReturn(stocks);

mvc.perform(get("/api/v1/stocks")).andDo(print()).andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(content().contentTypeCompatibleWith(APP_ContentType)).andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].stockCode", is(stock1.getStockCode())))
.andExpect(jsonPath("$[0].stockName", is(stock1.getStockName())))
.andExpect(jsonPath("$[0].stockPrice", is(stock1.getStockPrice())))
.andExpect(jsonPath("$[0].stockPriceChange", is(stock1.getStockPriceChange())))
.andExpect(jsonPath("$[1].stockCode", is(stock2.getStockCode())))
.andExpect(jsonPath("$[1].stockName", is(stock2.getStockName())))
.andExpect(jsonPath("$[1].stockPrice", is(stock2.getStockPrice())))
.andExpect(jsonPath("$[1].stockPriceChange", is(stock2.getStockPriceChange())))
.andExpect(jsonPath("$[2].stockCode", is(stock3.getStockCode())))
.andExpect(jsonPath("$[2].stockName", is(stock3.getStockName())))
.andExpect(jsonPath("$[2].stockPrice", is(stock3.getStockPrice())))
.andExpect(jsonPath("$[2].stockPriceChange", is(stock3.getStockPriceChange())));

}

@Test
public void testGetStock() throws Throwable {

// prepare test data
Stock stock = new Stock();
stock.setStockCode("abc");
stock.setStockName("name 1");
stock.setStockPrice(1.111);
stock.setStockPriceChange(-0.111);

Mockito.when(stockService.findByStockCode(stock.getStockCode())).thenReturn(stock);

mvc.perform(get("/api/v1/stocks/{code}", stock.getStockCode())).andDo(print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(content().contentTypeCompatibleWith(APP_ContentType))
.andExpect(jsonPath("$.stockCode", is(stock.getStockCode())))
.andExpect(jsonPath("$.stockName", is(stock.getStockName())))
.andExpect(jsonPath("$.stockPrice", is(stock.getStockPrice())))
.andExpect(jsonPath("$.stockPriceChange", is(stock.getStockPriceChange())));
}

}


=================== ==========================
with eclipse, if encounter this exception as follows,

java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package

open "Configure Build Path" and select "Library" tab, remove "Junit" from the build path. The root cause is jar conflict with plug in "Hamctest" inside eclipse.

Tuesday, September 22, 2015

Autowired not working for repository in spring boot

in spring boot, beside @SpringBootApplication, need to add the following 3 annotations to make @Autowired to init jpa repository objects.


@SpringBootApplication
@ComponentScan(basePackages = { "com.abc" })
@EnableJpaRepositories(basePackages = { "com.abc.repository" })
@EntityScan(basePackages = "com.abc.repository.entity")
public class WebApplication extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebApplication.class);
}

public static void main(String[] args) throws Exception {
SpringApplication.run(WebApplication.class, args);
}
}

Friday, January 9, 2015

Maven Jetty PermGen space

before run "mvn jetty:run"

run this command in window env

set MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=512m

or unix-like env
export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=512m"

Friday, January 2, 2015

Spring MVC read properties in the class

This is sample code:

@Component( "emailService" )
public class EmailService {

  @Value( "${mail.server.url}" )
  private String url;

....
}

in the property file
mail.server.ur=http://abc/def