일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 프로그래머스
- db
- Git
- GitHub
- mybatis
- 생성
- Eclipse
- IntelliJ
- aws
- Vue
- 함수
- jquery
- 스프링
- oracle
- 에러
- 넥사크로
- 알고리즘
- Security
- 방법
- 오라클
- 시큐리티
- Java
- error
- kotlin
- JPA
- 자바
- JavaScript
- 쿼리
- Spring
- 코틀린
- Today
- Total
송민준의 개발노트
Junit 본문
Junit 이란?
1. Java에서 독립된 단위테스트를 지원해주는 프레임워크이다.
2. @RunWith는 JUnit 프레임워크의 테스트 실행방법을 확장할 때 사용하는 어노테이션이다.
@RunWith(SpringJUnit4ClassRunner.class)
- SpringJUnit4ClassRunner라는 JUnit용 테스트 컨텍스트 프레임워크 확장 클래스를 지정해 주면
JUnit이 테스트를 진행하는 중 테스트가 사용할 어플리케이션 컨텍스트를 만들고 관리하는 작업을 해준다.
3. @ContextConfiguration(locations="/applicationContext")
- 자동으로 만들어줄 어플리케이션 컨텍스트의 설정파일의 위치를 지정할 때 사용한다.
예제 경로
pom.xml : junit이 최초에 4.7로 기본 세팅이 되어 있는데 이대로 실행하면 에러가 나고 4.12로 하향시켜줘야 한다.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
_1DataSourceTest.java
package com.portfordev.pro;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class _1DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void testConnection() throws Exception {
try(Connection conn = dataSource.getConnection()) {
System.out.println("확인용 conn : " + conn);
} catch(Exception e) {
e.printStackTrace();
}
}
@Test
public void testQuery() throws Exception {
try(Connection conn = dataSource.getConnection()) {
PreparedStatement pstmt = conn.prepareStatement(
"select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'), user_name "
+ "from user_table");
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
System.out.println("현재 시각 : " + rs.getString(1));
System.out.println("사용자명 : " + rs.getString(2));
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
root-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- dev local dataSource -->
<bean class ="org.apache.commons.dbcp.BasicDataSource" id="dataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="scott"/>
<property name="password" value="TIGER"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property ref="dataSource" name="dataSource"/>
<property name="configLocation" value="classpath:util/SqlMapConfig.xml"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" index="0"/>
</bean>
<!-- 트랜잭션 처리 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 1024*1024*10 bytes : 10MB -->
<property name="maxUploadSize" value="10485760" />
</bean>
</beans>
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<typeAliases>
<typeAlias alias="member" type="com.portfordev.pro.domain.Member"/>
</typeAliases>
<mappers>
<mapper resource="sql/member.xml"/>
</mappers>
</configuration>
sql파일
/* test 파일 */
create table user_table(
today date,
user_name varchar2(20)
);
insert into user_table values(sysdate, '홍길동');
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'), user_name from user_table;
create table member_test3(
num varchar2(20),
name varchar2(30),
email varchar2(20),
tel varchar2(20),
addr varchar2(30),
today date
);
Run as Junit 결과(RDS와 테스트를 해보니 속도 차이가 3배 정도 난다.)
----------------------mybatis 연결-------------------------------------
package com.portfordev.pro;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class _1DataSourceTest {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Test
public void testConnection() throws Exception {
System.out.println("~~~~sqlSessionFactory : "+
sqlSessionFactory);
//sqlSessionFactory : org.apache.ibatis.session.defaults.Default
//만약에 root-context.xml 파일에 설정한 SqlSessionFactoryBean의 설정
}
@Test
public void testQuery() throws Exception {
try(SqlSession sqlsession = sqlSessionFactory.openSession()) {
System.out.println("~~~sqlsession : " + sqlsession);
} catch(Exception e) {
e.printStackTrace();
}
}
}
---------------------------------mybatis 활용----------
1. 먼저 org.slf4j 패키지의 Logger, LoggerFactory 클래스를 import를 해야한다.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2. LoggerFactory 클래스의 getLogger() 메소드를 통해 Logger 객체를 생성한다.
3. .class로 클래스 정보를 넘겨주면 그 클래스에 대한 로그를 실행한다.
member.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Members">
<insert id="insert" parameterType="MyBatisTestVO2">
insert into member_test3
values(
(select nvl(max(num),0)+1 from member_test3),
#{name}, #{email}, #{tel}, #{addr}, sysdate
)
</insert>
</mapper>
_1DataSourceTest.java
package com.portfordev.pro;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.portfordev.pro.domain.MyBatisTestVO2;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class _1DataSourceTest {
private static final Logger logger
= LoggerFactory.getLogger(_1DataSourceTest.class);
@Autowired
private SqlSessionTemplate sqlsession;
@Test
public void testCreate() throws Exception {
MyBatisTestVO2 vo = new MyBatisTestVO2();
vo.setName("D반");
vo.setEmail("D@gmailc.om");
vo.setTel("010010");
vo.setAddr("서울시 종로구");
int n = sqlsession.insert("Members.insert", vo);
logger.info("~~~~~~~~~~~~~~n : " + n + "~~~~~~~~~~~~~~~~~~");
}
}
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<typeAliases>
<typeAlias alias="MyBatisTestVO2" type="com.portfordev.pro.domain.MyBatisTestVO2"/>
</typeAliases>
<mappers>
<mapper resource="sql/member.xml"/>
</mappers>
</configuration>
MyBatisTestVO2.java
package com.portfordev.pro.domain;
import java.sql.Date;
import lombok.Data;
@Data
public class MyBatisTestVO2 {
private String num;
private String name;
private String email;
private String tel;
private String addr;
private Date date;
}
결과
-----------------------조회-------------------------------------
_1DataSourceTest.java 에서 select 할 test코드 추가
package com.portfordev.pro;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.portfordev.pro.dao.MemberDAO;
import com.portfordev.pro.domain.MyBatisTestVO2;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class _1DataSourceTest {
private static final Logger logger
= LoggerFactory.getLogger(_1DataSourceTest.class);
@Autowired
private SqlSessionTemplate sqlsession;
//@Test
public void testCreate() throws Exception {
MyBatisTestVO2 vo = new MyBatisTestVO2();
vo.setName("D반");
vo.setEmail("D@gmailc.om");
vo.setTel("010010");
vo.setAddr("서울시 종로구");
int n = sqlsession.insert("Members.insert", vo);
logger.info("~~~~~~~~~~~~~~n : " + n + "~~~~~~~~~~~~~~~~~~");
}
@Test
public void testSelect() throws Exception {
MyBatisTestVO2 vo = sqlsession.selectOne("Members.testidcheck", "1");
System.out.println(vo.toString());
}
}
member.xml
<select id="testidcheck" parameterType="String" resultType="MyBatisTestVO2">
select *
from member_test3
where num = #{inputid}
</select>
결과
------------------------selectList 써보기-------------------------------------
_1DataSourceTest.java 에서 selectList 할 test코드 추가
@Test
public void testAllSelect() throws Exception {
List<MyBatisTestVO2> list = sqlsession.selectList("Members.selectAll");
list.forEach(item ->{
System.out.println(item);
});
}
member.xml
<select id ="selectAll" resultType="MyBatisTestVO2">
select * from member_test3
</select>
결과
-----------------------------톰캣없이 Controller 테스트 --------------------------------
단위 테스트를 위해서 SpringJUnit4ClassRunner라는 Runner클래스를 사용한다.
@RunWith(SpringJUnit4ClassRunner.class)
WAS 없이 MVC 패턴의 COntroller를 단위 테스트 하기 위해서는
@WebAppConfiguration을 사용해야만 한다.(스프링 MVC 테스트할때 사용하는것)
이 어노테이션을 붙이면 Controller 및 web환경에 사용되는 빈들을 자동으로 생성하여 등록합니다.
_4MyBatisTestControllerTestDEPT.java
package com.portfordev.pro;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
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.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class _4MyBatisTestControllerTestDEPT {
private static final Logger logger
= LoggerFactory.getLogger(_4MyBatisTestControllerTestDEPT.class);
@Autowired
private WebApplicationContext wac;
//웹 어플리케이션을 어플리케이션 서버에 배포하지 않고도 스프링 MVC 동작을 재현할 수 있는 클래스
private MockMvc mockMvc;
// 매번 테스트를 진행할때 마다 테스트 하기전 MockMvc mockMvc 객체를 만들어 주기 위해
// Before 어노테이션으로 setup() 메소드를 실행
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
logger.info("setup~~~~");
}
@Test
public void testMyBatisTest() throws Exception {
logger.info("===testMybatisTest() =====");
try {
// .perform()을 이용하면 매핑 url로 request(요청)합니다.
// .andExpect를 이용해서 다양하게 검증할 수 있다.
// status().isOk()는 응답을 받아 HttpStatus 코드가 "200"인지 체크할 수 있다.
mockMvc.perform(post("/mybatistest/mybatisDeptinsert")
.param("deptno","55")
.param("dname","Dclass")
.param("loc", "Seoul2"))
.andDo(print())
.andExpect(status().isOk()) // 응답을 받아 HttpStatus 코드가 200인지
//.andExpect(status().isForbidden()) // 403
.andExpect(model().attributeExists("result")) //result attribute가
.andExpect(view().name("memberRegisterDept")); //view의 이름이 memberRegisterDept인지
logger.info("~~~ 수행 성공 ~~~");
} catch(Exception e) {
logger.error(">> 수행 실패 : " + e.getMessage());
}
}
}
controller.java
@RequestMapping(value = "/mybatistest/mybatisDeptinsert", method = {RequestMethod.POST})
public ModelAndView mybatisDeptinsert(HttpServletRequest request, ModelAndView mv) {
try {
String deptno = request.getParameter("deptno");
String loc = request.getParameter("loc");
String dname = request.getParameter("dname");
HashMap<String, String> paraMap = new HashMap<String, String>();
paraMap.put("deptno", deptno);
paraMap.put("loc", loc);
paraMap.put("dname", dname);
int n = memberservice.memberRegisterDept(paraMap);
String result = "";
if(n == 1)
result = "삽입 성공!!";
else
result = "삽입 실패!!";
mv.addObject("result", result);
mv.setViewName("memberRegisterDept");
} catch(Exception e) {
mv.addObject("error", "상ㅂ입 중 오류가 발생했습니다.");
mv.setViewName("error");
}
return mv;
}
member.xml
<insert id = "registerDept" parameterType = "map">
INSERT INTO DEPT
VALUES(#{deptno}, #{dname}, #{loc})
</insert>
MemberDAO.java
public int memberRegisterDept(HashMap<String, String> map) {
return sqlSession.insert("Members.registerDept", map);
}
MemberServiceImpl.java
@Override
public int memberRegisterDept(HashMap<String, String> map) {
return dao.memberRegisterDept(map);
}
결과
MockHttpServletRequest:
HTTP Method = POST
Request URI = /mybatistest/mybatisDeptinsert
Parameters = {deptno=[55], dname=[Dclass], loc=[Seoul2]}
Headers = {}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.portfordev.pro.controller.MemberController
Method = public org.springframework.web.servlet.ModelAndView com.portfordev.pro.controller.MemberController.mybatisDeptinsert(javax.servlet.http.HttpServletRequest,org.springframework.web.servlet.ModelAndView)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = memberRegisterDept
View = null
Attribute = modelAndView
value = ModelAndView [view="memberRegisterDept"; model={result=삽입 성공!!}]
errors = []
Attribute = result
value = 삽입 성공!!
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Language=[en]}
Content type = null
Body =
Forwarded URL = /WEB-INF/views/memberRegisterDept.jsp
Redirected URL = null
Cookies = []
INFO : com.portfordev.pro._4MyBatisTestControllerTestDEPT - ~~~ 수행 성공 ~~~
'웹 > Spring Framework' 카테고리의 다른 글
(Spring) kakao 소셜 로그인(SSO, oauth) (0) | 2020.01.10 |
---|---|
프로젝트 import 후 tomcat에 add 안될 때 (0) | 2020.01.09 |
mybatis null값 처리 (0) | 2020.01.08 |
transaction (0) | 2020.01.03 |
AOP(Aspect Oriented Programming) (0) | 2020.01.02 |