public interface ICalculator {
int sum(int x, int y);
int minus(int x, int y);
void init();
}
@Component
@RequiredArgsConstructor
public class Calculator {
private final ICalculator iCalculator;
public int sum(int x, int y){
// 시세 반영 시킨후 계산
this.iCalculator.init();
return this.iCalculator.sum(x,y);
}
public int minus(int x, int y){
this.iCalculator.init();
return this.iCalculator.minus(x, y);
}
}
@Component
@RequiredArgsConstructor
public class DollarCalculator implements ICalculator {
private int price = 1;
private final MarketApi marketApi;
public void init(){
this.price = marketApi.connect();
}
@Override
public int sum(int x, int y) {
x *= price;
y *= price;
return x + y;
}
@Override
public int minus(int x, int y) {
x *= price;
y *= price;
return x - y;
}
}
@Component
public class MarketApi {
public int connect(){
return 1100;
}
}
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CalculatorApiController {
private final Calculator calculator;
@GetMapping("/sum")
public int sum(@RequestParam int x, @RequestParam int y){
return calculator.sum(x,y);
}
@PostMapping("/minus")
public Res minus(@RequestBody Req req){
int result = calculator.minus(req.getX(), req.getY());
Res res = new Res();
res.setResult(result);
res.setResponse(new Res.Body());
return res;
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Req {
private int x;
private int y;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Res {
private int result;
private Body response;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Body{
private String resultCode = "OK";
}
}
@SpringBootTest
@Import({MarketApi.class, DollarCalculator.class})
public class DollarCalculatorTest {
@MockBean
private MarketApi marketApi;
@Autowired
private DollarCalculator dollarCalculator;
@Test
public void dollarCalculatorTest(){
Mockito.when(marketApi.connect()).thenReturn(3000);
// 이게 없으면 값이 그냥 20으로 나옴
dollarCalculator.init();
int sum = dollarCalculator.sum(10, 10);
int minus = dollarCalculator.minus(10,10);
Assertions.assertEquals(60000, sum);
Assertions.assertEquals(0, minus);
}
}
@WebMvcTest(CalculatorApiController.class)
@AutoConfigureWebMvc
// Calculator가 ICalculator 주입 받고 있어서 Dollar*.class 넣어 주었고
// Dollar 안 MarketApi는 Mock으로 처리
@Import({Calculator.class, DollarCalculator.class })
public class CalculatorApiControllerTest {
@MockBean
private MarketApi marketApi;
@Autowired
private MockMvc mockMvc;
@BeforeEach
private void init(){
Mockito.when(marketApi.connect()).thenReturn(3000);
}
@Test
public void sumTest() throws Exception {
// http://localhost:8080/api/sum
mockMvc.perform(
MockMvcRequestBuilders.get("http://localhost:8080/api/sum")
.queryParam("x","10")
.queryParam("y", "10")
).andExpect(
MockMvcResultMatchers.status().isOk()
).andExpect(
MockMvcResultMatchers.content().string("60000")
).andDo(MockMvcResultHandlers.print());
}
@Test
public void minusTest() throws Exception {
Req req = new Req();
req.setX(10);
req.setY(10);
String json = new ObjectMapper().writeValueAsString(req);
mockMvc.perform(
MockMvcRequestBuilders.post("http://localhost:8080/api/minus")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
).andExpect(
MockMvcResultMatchers.status().isOk()
).andExpect(
MockMvcResultMatchers.jsonPath("$.result").value("0")
).andExpect(
MockMvcResultMatchers.jsonPath("$.response.resultCode").value("OK")
).andDo(
MockMvcResultHandlers.print()
);
}
}
각각 어노테이션 및 테스트 코드 동작 원리를 제대로 이해하자..
아직 헷갈림