### : 목차 구분 기호
--- : 목차 내에 항목 구분 기호
@@@ : 태그 용도
,,, : 같은 목차 내에 구분 기호

목차
1. 이론 및 정보
2. 설정 및 그 밖에
3. 소스코드 또는 실습
4. 과제

###################################
1. 이론 및 정보
-----------------------------------
* AOP(Aspect Oriented Programming) - Spring을 대표하는 기능
... 이어서

4) 구현 방법
          ㄱ) 스프링에서 제공하는 객체
                    MethodBeforeAdvice
                    AfterReturningAdvice
                    ThrowsAdvice
                    MethodInterceptor

          ㄴ) POJO - 일반클래스 이용
                    ProceedingJoinPoint
                    org.aspectj.aspectweaver

          ㄷ) Annotation
                    @Aspect, @Around, ...
                    org.aspectj.aspectweaver
          
-----------------------------------
* JUnit : 단위 테스트 프레임워크

TDD : Test Driven Develop - 테스트 주도 개발 방식

소프트웨어 개발론
1. 폭포수 개발
2. Agile
     - XP : agile, xp를 융합해서 많이 씀
          ㄱ. pair coding 짝코딩 : 한명이 없어도 일을 개발할 수 있음
          ㄴ. TDD : 테스트를 먼저함, 테스트 코드를 만드는데 JUnit을 사용

왜 TDD를 써야하나?
1. 고전적인 개발 방식에서 나타날 수 있는 문제
          - 특정 모듈 개발 기간이 길어질 수록 개발자의 목표의식이 흐려진다.
          - 작업 분량이 늘어날 수록 확인이 어려워진다.
          - 개발자의 집중력이 필요해진다.
          - 논리적인 오류를 찾기가 힘들다.
          - 코드의 사용법과 변경 이력을 개발자의 기억력에 의존하게 되는 경우가 많다.
          - 코드 수정시에 기존 코드의 정상 동작에 대한 보장이 어렵다.

어록? Test the program before you write it. - kent back
=> 테스트에 맞춰서 코드를 짜라

Clean code that works - Ron Jeffries
=> 테스트 하면서 코드도 리팩토링해 가는 방식
테스트 -> 코드 수정 -> 리팩토링 -> 테스트 -> ...

-----------------------------------
* TDD 예제1 시나리오 - first 패키지

메서드명 : sum
Argument : int a, int b
Return Type : int
Condition : a와 b를 더한 값을 결과로 돌려 줌
-----------------------------------
* TDD Cycle

1. 질문 - 코드가 맞는지 질문을 함
2. 응답 - 질문에 해결책
3. 정제 - 리팩토링

이 흐름을 계속 반복해 나가는 과정 TDD

-----------------------------------
* TDD 예제2 시나리오 - 실습 3-6, bank 패키지

기본 시나리오
          은행 계좌 클래스
               - 계좌 잔고 조회
               - 입급 / 출금
               - 예상 복리 이자(추가)
               ...

          첫번째 질문 : 계좌 생성 테스트
               class name : Account
               function
                    - 잔고 조회
                    - 입금
                    - 출금
                    ...
               desc : 금액은 원 단위(예 : 천원 = 1000)

          첫번째 응답 : 계좌 생성 구현

          첫번째 정제 :
                    - 소스의 가독성이 적절한가?
                    - 중복된 코드는 없는가?
                    - 이름이 잘 못 부여된 메서드나 변수는 없는가?
                    - 구조의 개선이 필요한 부분은 없는가?

          두번째 질문 - JUnit을 사용
                    - 잔고 조회 기능 작성을 위한 테스트 케이스(@Test 붙여라) 작성
                    - 테스트 수행 결과가 errors로 표시된 항목은 failures로 만든다.

          class name : Account
          function
                    - 잔고 조회
                              10000원 계좌 생성
                              잔고 조회 결과 일치

          두번째 응답 : 잔고 조회 기능 구현

          두번째 정제
                    - 변수명 고침 : i 변수를 money로 교체
                    - JUnit에서 제공하는 메서드 사용 : if문 대신 assertEquals()로 교체


          세번째 질문
                    - 입금
                              10000원으로 계좌 생성
                              1000원 입금
                              잔고가 11000원 확인
                    - 출금
                              10000원으로 계좌 생성
                              1000원 출금
                              잔고가 9000원 확인


          세번째 응답 : 입금과 출금 기능 구현
          
          세번째 정제
                    변수명을 의미있게 수정

                              
-----------------------------------
* 예전 개발방식의 문제점
폭포수 개발 방식에서는 절반 이상에 테스트와 디버깅 하는데 씀
TDD는 이러한 시간을 소비를 줄일 수 있음
-----------------------------------
* 하나의 테스트는 반드시 하나의 기능만 테스트를 하라!!
-----------------------------------
* JUnit 사용
버전 3, 버전 4 있는데
3버전이 오래쓰임

두 버전의 차이?
version 3 : 상속 사용, 메서드 접두사로 'test'가 들어갔음
version 4 : annotation 사용

테스트 케이스 : 테스트 할 수 있는 클래스

JUnit도 git, maven처럼 cmd 명령으로 사용할 수 있는데
이클립스에 내장되어 있음, 많이 사용하니까

내장은 되어있으나 프로젝트에 빌드path를 연결해줘야 한다
or @Test 적고 에러난 부분에서 Alert Icon을 이용해서 자동 추가


JUnit Errors의 문제는 개발자의 능력에 문제? 코드의 문제
JUnit Failures 를 많이 찾아내는게 JUnit을 가장 큰 사용 목적

JUnit에서 에러 발생 시킬때 사용하는 메서드
fail();
-----------------------------------
* TDD 장점
1) 개발의 방향을 잃지 않도록 유지해 준다.
2) 품질 높은 소프트웨어 모듈을 보유
3) 자동화된 단위 테스트를 갖게 된다.
4) 사용설명서 & 의사소통의 수단
5) 설계 개선
6) 보다 자주 성공
-----------------------------------
* JUnit의 사용법을 익혀서 이력서에 넣을 정도가 되어라
-----------------------------------
* Spring의 Mock 객체(유사한, Sample)
DB가 있는 것처럼 제공
-----------------------------------
###################################
2. 설정 및 그 밖에
-----------------------------------
* 프로젝트 생성
Maven Project
Group ID - com.study.myproject
Artifact ID - AopTest
-----------------------------------
* 패키지 생성
스프링의 도움으로 만들 패키지
/AopTest/src/main/java/myaop

스프링 도움없이 만들 패키지
/AopTest/src/main/java/mypojo
/AopTest/src/main/java/myanno
-----------------------------------
* 프로젝트 생성
Java Project
/TDDPractice
-----------------------------------
###################################
3. 소스코드 또는 실습
-----------------------------------
3-1

프로젝트 생성 및 라이브러리 설정

Workspace : ~\study\SpringWork  

/AopTest/pom.xml

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.study.myproject</groupId>
     <artifactId>AopTest</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>AopTest</name>
     <url>http://maven.apache.org</url>
 
     <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
 
     <dependencies>
          <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>3.8.1</version>
               <scope>test</scope>
          </dependency>
          <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-context</artifactId>
               <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
               <groupId>javax.annotation</groupId>
               <artifactId>jsr250-api</artifactId>
               <version>1.0</version>
          </dependency>
     </dependencies>
</project>

    

-----------------------------------

3-2

/AopTest/src/main/java/myaop 패키지

AOP를 SPRING을 이용해서 구현

 

Workspace : ~\study\SpringWork

/AopTest/src/main/java/myaop/myaop_config.xml

Spring Bean Configuration File로 만듬

 

/AopTest/src/main/java/myaop/App.java

/AopTest/src/main/java/myaop/MessageBean.java

/AopTest/src/main/java/myaop/MessageBeanImpl.java

 

메서드 성능테스트 구현할 예정

시간을 측정하는 코드가 기존 코드에 삽입이 될 예정

그런데 이 코드들이 수십,수백개의 메서드에서 쓰이니까

코드를 분리 할텐데, 분리한 코드를 다시 불러서 쓰게 됨

또한 시간을 측정해야하는 메서드들이 지금 사용중인지

모니터링을 해야하는데 이점이 어려움

 

이러한 어려움을 AOP로 해결할 것임

 

Advice로 사용할 클래스 만듬, MethodInterceptor를 씀 Around Advice를 써야 하니까

/AopTest/src/main/java/myaop/LoggingAdvice.java

 

 

LoggingAdvice가 MessageBeanImpl의 sayHello()를 감시할 것임

 

 

포인트컷이 어디인지 알려줘야함 -> 설정 파일에서 설정을 함

/AopTest/src/main/java/myaop/myaop_config.xml

 

이번에 예제의 Target Class는 MessageBeanImpl

 

 

 
/AopTest/src/main/java/myaop/App.java
 
package myaop;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("myaop/myaop_config.xml");
        
        MessageBean bean = ctx.getBean("proxy", MessageBean.class);
        bean.sayHello();
    }
}
 
 
/AopTest/src/main/java/myaop/LoggingAdvice.java
 
package myaop;
 
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;
 
public class LoggingAdvice implements MethodInterceptor{
    
//    invoke() 메서드가 두번 실행 되는 메서드
//    매개변수에 가로채고자 하는 것이 전달됨    
    public Object invoke(MethodInvocation arg0) throws Throwable {
        StopWatch watch = new StopWatch();
        String methodName = arg0.getMethod().getName();
        
        // 시계 구별 용도를 설정하면서 시작
        watch.start(methodName);
        System.out.println("[LOG]Method : "+methodName+" 시작됨");
        
        // 중지된 메서드 다시 실행, 정상진행이 되는지 결과값을 받음
        // 결과값을 반드시 리턴해야 진행이 됨
        Object obj = arg0.proceed();
        
        // 중지된 메서드의 내용이 전부 실행 되고, 시간 측정
        watch.stop();
        System.out.println("[LOG]Method : "+methodName+" 종료");        
        
        System.out.println("[LOG]처리시간 : "+watch.getTotalTimeSeconds()+"초");
        return obj;
    }
}
 
 
/AopTest/src/main/java/myaop/MessageBean.java
 
package myaop;
 
public interface MessageBean {
    void sayHello();
}
 
 
/AopTest/src/main/java/myaop/MessageBeanImpl.java
 
package myaop;
 
public class MessageBeanImpl implements MessageBean {
    private String name;
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void sayHello() {
        // 시작시간을 측정하여 로그에 기록하고 화면에 출력
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("안녕하세요~~" + name + "님!");
        // 끝나는시간을 측정하여 로그에 기록하고 화면에 출력
        // 총 걸린 시간을 로그에 기록하고 화면출력
    }
 
}

    

 
/AopTest/src/main/java/myaop/myaop_config.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="messageBean" class="myaop.MessageBeanImpl">
        <property name="name" value="홍길동"></property>
    </bean>
    <bean id="loggingAdvice" class="myaop.LoggingAdvice"></bean>
    <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut">
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern">
                    <value>.*sayHello.*</value>
                </property>
            </bean>
        </property>
        <property name="advice" ref="loggingAdvice"/>
    </bean>
    
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="messageBean"/>
        <property name="interceptorNames">
            <list>
                <value>advisor</value>
            </list>
        </property>
    </bean>
</beans>

    

 

-----------------------------------

3-3

/AopTest/src/main/java/mypojo 패키지

에서 스프링에서 지원하지 않는 AOP 실습

 

Workspace : ~\study\SpringWork

 

다운로드 받아야함

 

/AopTest/pom.xml 추가

<dependency>

     <groupId>org.aspectj</groupId>

     <artifactId>aspectjweaver</artifactId>

     <version>1.8.6</version>

</dependency>

 

기존의 코드는 수정하지 않아도 됨

/AopTest/src/main/java/mypojo/MessageBean.java

/AopTest/src/main/java/mypojo/MessageBeanImpl.java

 

아래 파일들은 수정

/AopTest/src/main/java/mypojo/LoggingAdvice.java

/AopTest/src/main/java/mypojo/mypojo_config.xml

AOP Namespaces에서 AOP 추가

 

<bean id="loggingAdvice" class="myaop.LoggingAdvice"></bean>

를 지우고 어노테이션으로 함

 

/AopTest/src/main/java/mypojo/App.java
 
package mypojo;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("mypojo/mypojo_config.xml");
        
        MessageBean bean = ctx.getBean("messageBean", MessageBean.class);
        bean.sayHello();
    }
}
 
 
/AopTest/src/main/java/mypojo/LoggingAdvice.java
 
package mypojo;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
 
@Component
public class LoggingAdvice {
    
//    invoke() 메서드가 두번 실행 되는 메서드
//    매개변수에 가로채고자 하는 것이 전달됨    
    public Object invoke(ProceedingJoinPoint arg0) throws Throwable {
        StopWatch watch = new StopWatch();
        String methodName = arg0.getSignature().getName();
        
        // 시계 구별 용도를 설정하면서 시작
        watch.start(methodName);
        System.out.println("[LOG]Method : "+methodName+" 시작됨");
        
        // 중지된 메서드 다시 실행, 정상진행이 되는지 결과값을 받음
        // 결과값을 반드시 리턴해야 진행이 됨
        Object obj = arg0.proceed();
        
        // 중지된 메서드의 내용이 전부 실행 되고, 시간 측정
        watch.stop();
        System.out.println("[LOG]Method : "+methodName+" 종료");        
        
        System.out.println("[LOG]처리시간 : "+watch.getTotalTimeSeconds()+"초");
        return obj;
    }
}
 
/AopTest/src/main/java/mypojo/MessageBean.java
 
package mypojo;
 
public interface MessageBean {
    void sayHello();
}
 
 
/AopTest/src/main/java/mypojo/MessageBeanImpl.java
 
package mypojo;
 
public class MessageBeanImpl implements MessageBean {
    private String name;
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void sayHello() {
        // 시작시간을 측정하여 로그에 기록하고 화면에 출력
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("안녕하세요~~" + name + "님!");
        // 끝나는시간을 측정하여 로그에 기록하고 화면에 출력
        // 총 걸린 시간을 로그에 기록하고 화면출력
    }
 
}

    

/AopTest/src/main/java/mypojo/mypojo_config.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
    <context:component-scan base-package="mypojo"/>
    <bean id="messageBean" class="mypojo.MessageBeanImpl">
        <property name="name" value="임꺽정"></property>
    </bean>
        
    <aop:config>
        <aop:aspect id="logging" ref="loggingAdvice">
            <aop:pointcut expression="execution(* sayHello())" id="logPointcut"/>
            <aop:around method="invoke" pointcut-ref="logPointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

    

-----------------------------------  

3-4

/AopTest/src/main/java/myanno 패키지

가장 간단하게 코드를 줄일 수 있는 AOP 실습

 

Workspace : ~\study\SpringWork

 

mypojo 패키지에서 다운 받은 라이브러리를 사용할 것임

 

 

이번 예제에서도 mypojo 처럼 수정할 것만 수정하면 됨

/AopTest/src/main/java/myanno/LoggingAdvice.java

/AopTest/src/main/java/myanno/App.java

/AopTest/src/main/java/myanno/myanno_config.xml

 

/AopTest/src/main/java/myanno/App.java
 
package myanno;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("myanno/myanno_config.xml");
        
        MessageBean bean = ctx.getBean("messageBean", MessageBean.class);
        bean.sayHello();
    }
}
 
/AopTest/src/main/java/myanno/LoggingAdvice.java
 
package myanno;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
 
@Component
@Aspect
public class LoggingAdvice {
    
//    invoke() 메서드가 두번 실행 되는 메서드
//    매개변수에 가로채고자 하는 것이 전달됨
    @Around("execution(* sayHello())")
    public Object invoke(ProceedingJoinPoint arg0) throws Throwable {
        StopWatch watch = new StopWatch();
        String methodName = arg0.getSignature().getName();
        
        // 시계 구별 용도를 설정하면서 시작
        watch.start(methodName);
        System.out.println("[LOG]Method : "+methodName+" 시작됨");
        
        // 중지된 메서드 다시 실행, 정상진행이 되는지 결과값을 받음
        // 결과값을 반드시 리턴해야 진행이 됨
        Object obj = arg0.proceed();
        
        // 중지된 메서드의 내용이 전부 실행 되고, 시간 측정
        watch.stop();
        System.out.println("[LOG]Method : "+methodName+" 종료");        
        
        System.out.println("[LOG]처리시간 : "+watch.getTotalTimeSeconds()+"초");
        return obj;
    }
}
 
/AopTest/src/main/java/myanno/MessageBean.java
 
package myanno;
 
public interface MessageBean {
    void sayHello();
}
 
/AopTest/src/main/java/myanno/MessageBeanImpl.java
 
package myanno;
 
public class MessageBeanImpl implements MessageBean {
    private String name;
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void sayHello() {
        // 시작시간을 측정하여 로그에 기록하고 화면에 출력
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("안녕하세요~~" + name + "님!");
        // 끝나는시간을 측정하여 로그에 기록하고 화면에 출력
        // 총 걸린 시간을 로그에 기록하고 화면출력
    }
 
}

    

/AopTest/src/main/java/myanno/myanno_config.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
    <context:component-scan base-package="myanno"/>
    
    <bean id="messageBean" class="myanno.MessageBeanImpl">
        <property name="name" value="신돌석"></property>
    </bean>    
    
    <aop:aspectj-autoproxy/>
</beans>

    

-----------------------------------  

3-5

/TDDPractice TDD 연습

/TDDPractice/first 패키지

 

Workspace : ~\study\SpringWork

 

/TDDPractice/src/first/Calculator.java

 

 
/TDDPractice/src/first/Calculator.java
 
package first;
 
public class Calculator {
    public int sum(int a, int b){
        return 0;
    }
    
    public static void main(String[] args) {
        Calculator cal = new Calculator();
        System.out.println(cal.sum(10, 20)==30);
        System.out.println(cal.sum(1, 2)==3);
        System.out.println(cal.sum(-10, 20)==10);
        System.out.println(cal.sum(0, 0)==0);
    }
}
 

    

-----------------------------------  

3-6

TDD 예제2 시나리오 - 첫번째 질문

 

Workspace : ~\study\SpringWork

 

코드(main 패키지)와 테스트(test 패키지) 코드를 분리시키는게 관리에 유리

 

/TDDPractice/bank/main

/TDDPractice/bank/test

패키지 생성

 

/TDDPractice/src/bank/test/AccountTest.java

/TDDPractice/src/bank/main/Account.java

 

-----------------------------------

3-7

TDD 예제2 시나리오 - 두번째 질문 - JUnit

Workspace : ~\study\SpringWork

 

JUnit을 사용하면 main 메서드를 만들 필요 없음

/TDDPractice/src/bank/test/AccountTest.java

 

기존 main지우고 testAccount()에 @Test 어노테이션 붙임

에러아이콘 눌러서 Build Path에 JUnit 4 추가

 

 

실행방법

menu - run - run as - junit test

프로젝트 우클릭 - run as - junit

 

Green Light가 나오면 성공임

 

-----------------------------------

3-8

TDD 예제2 시나리오 - 세번째 질문

 

Workspace : ~\study\SpringWork

 

중복된 변수(account) 우클릭 - Quick Fix or Refactor - Covert local to Field

 

중복된 인스턴스 생성을 메서드로 뺀다 account

account = new Account(10000); 를 블록 잡고 우클릭

Refactor - extract method

-----------------------------------

/TDDPractice/src/bank/test/AccountTest.java

 

package bank.test;
 
import static org.junit.Assert.assertEquals;
 
import org.junit.Test;
 
import bank.main.Account;
 
public class AccountTest {
    private Account account;
    @Test
    public void testAccount() throws Exception {
        setup();
    }
    @Test
    public void testGetBalance(){
        setup();
        assertEquals(10000, account.getBalance());
        
        account = new Account(1000);
        assertEquals(1000, account.getBalance());
        
        account = new Account(100);
        assertEquals(100, account.getBalance());
    }
    @Test
    public void testDeposit(){
        setup();
        account.deposit(1000);
        assertEquals(11000, account.getBalance());        
    }
    public void setup() {
        account = new Account(10000);
    }
    @Test
    public void testWithdraw(){
        setup();
        account.widthdraw(1000);
        assertEquals(9000, account.getBalance());
    }
}
 
// 3-8 정제
//package bank.test;
//
//import static org.junit.Assert.assertEquals;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    private Account account;
//    @Test
//    public void testAccount() throws Exception {
//        setup();
//    }
//    @Test
//    public void testGetBalance(){
//        setup();
//        assertEquals(10000, account.getBalance());
//        
//        account = new Account(1000);
//        assertEquals(1000, account.getBalance());
//        
//        account = new Account(100);
//        assertEquals(100, account.getBalance());
//    }
//    @Test
//    public void testDeposit(){
//        setup();
//        account.deposit(1000);
//        assertEquals(11000, account.getBalance());        
//    }
//    public void setup() {
//        account = new Account(10000);
//    }
//    @Test
//    public void testWithdraw(){
//        setup();
//        account.widthdraw(1000);
//        assertEquals(9000, account.getBalance());
//    }
//}
 
// 3-8 errors, 3-8 Failures , 3-8 Success
//package bank.test;
//
//import static org.junit.Assert.assertEquals;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    @Test
//    public void testAccount() throws Exception {
//    }
//    @Test
//    public void testGetBalance(){
//        Account account = new Account(10000);
//        assertEquals(10000, account.getBalance());
//        
//        account = new Account(1000);
//        assertEquals(1000, account.getBalance());
//        
//        account = new Account(100);
//        assertEquals(100, account.getBalance());
//    }
//    @Test
//    public void testDeposit(){
//        Account account = new Account(10000);
//        account.deposit(1000);
//        assertEquals(11000, account.getBalance());        
//    }
//    @Test
//    public void testWithdraw(){
//        Account account = new Account(10000);
//        account.widthdraw(1000);
//        assertEquals(9000, account.getBalance());
//    }
//}
 
// 3-7 assertEquals
//package bank.test;
//
//import static org.junit.Assert.assertEquals;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    @Test
//    public void testAccount() throws Exception {
//    }
//    @Test
//    public void testGetBalance(){
//        Account account = new Account(10000);
//        assertEquals(10000, account.getBalance());
//        
//        account = new Account(1000);
//        assertEquals(1000, account.getBalance());
//        
//        account = new Account(100);
//        assertEquals(100, account.getBalance());
//    }
//}
 
 
// 3-7 테스트 여러개 늘림, 3-7 여러 테스트를 만족시킴
//package bank.test;
//
//import static org.junit.Assert.fail;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    @Test
//    public void testAccount() throws Exception {
//    }
//    @Test
//    public void testGetBalance(){
//        Account account = new Account(10000);
//        if (account.getBalance() != 10000) {
//            fail();
//        }
//        
//        account = new Account(1000);
//        if (account.getBalance() != 1000) {
//            fail();
//        }
//        
//        account = new Account(100);
//        if (account.getBalance() != 100) {
//            fail();
//        }
//    }
//}
 
// 3-7 Failures 발생시키기, 3-7 성공
//package bank.test;
//
//import static org.junit.Assert.fail;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    @Test
//    public void testAccount() throws Exception {
//    }
//    @Test
//    public void testGetBalance(){
//        Account account = new Account(10000);
//        if (account.getBalance() != 10000) {
            // JUnit에서 에러 발생 시킬때 사용하는 메서드
//            fail();
            // throw new Exception();
//        }
//    }
//}
 
// 3-7 Errors 발생시키기
//package bank.test;
//
//import org.junit.Test;
//
//import bank.main.Account;
//
//public class AccountTest {
//    @Test
//    public void testAccount() throws Exception {
//    }
//    @Test
//    public void testGetBalance(){
//        Account account = new Account(10000);
//        if(account.getBalance() != 10000){
//            throw new Exception();
//        }
//    }
//}
 
// 3-6 실습
//package bank.test;
//import bank.main.Account;
//public class AccountTest {
//    public void testAccount() throws Exception {
//        Account account = new Account();
//        if (account == null) {
//            throw new Exception("계좌 생성 실패");
//        }
//    }
//    public static void main(String[] args) {
//        AccountTest test = new AccountTest();
//        try {
//            test.testAccount();
//        } catch (Exception e) {
//            System.out.println("실패(X)");
//            return;
//        }
//        System.out.println("성공(O)");
//    }
//}

    

-----------------------------------

/TDDPractice/src/bank/main/Account.java

package bank.main;
 
public class Account {
    private int balance;
    public Account(int money) {
        balance = money;
    }
 
    public int getBalance() {
        return balance;
    }
 
    public void deposit(int money) {
        balance += money;
    }
 
    public void widthdraw(int money) {
        balance -= money;
    }
}
// 3-8 Success, 3-8 정제
//package bank.main;
//
//public class Account {
//    private int balance;
//    public Account(int money) {
//        balance = money;
//    }
//
//    public int getBalance() {
//        return balance;
//    }
//
//    public void deposit(int money) {
//        balance += money;
//    }
//
//    public void widthdraw(int money) {
//        balance -= money;
//    }
//}
 
// 3-8 Failures
//package bank.main;
//
//public class Account {
//    private int balance;
//    public Account(int money) {
//        balance = money;
//    }
//
//    public int getBalance() {
//        return balance;
//    }
//
//    public void deposit(int money) {
//    }
//
//    public void widthdraw(int money) {
//    }
//}
// 3-7 여러 테스트를 만족시킴, 3-8 errors
//package bank.main;
//
//public class Account {
//    private int balance;
//    public Account(int i) {
//        balance = i;
//    }
//
//    public int getBalance() {
//        return balance;
//    }
//}
 
// 3-7 성공, 3-7 테스트 여러개 늘림
//package bank.main;
//
//public class Account {
//
//    public Account(int i) {
//        // TODO Auto-generated constructor stub
//    }
//
//    public int getBalance() {
//        // TODO Auto-generated method stub
//        return 10000;
//    }
//}
 
// 3-7 Failures 발생시키기
//package bank.main;
//
//public class Account {
//
//    public Account(int i) {
//        // TODO Auto-generated constructor stub
//    }
//
//    public int getBalance() {
//        // TODO Auto-generated method stub
//        return 0;
//    }
//}
 
//3-6 실습, 3-7 Errors 발생시키기
//package bank.main;
//public class Account {
//}
 

    

-----------------------------------

###################################


'OpenFrameWork' 카테고리의 다른 글

오픈프레임워크_Day88  (0) 2015.07.17
오픈프레임워크_Day87  (0) 2015.07.16
오픈프레임워크_Day85  (0) 2015.07.14
오픈프레임워크_Day84  (0) 2015.07.13
오픈프레임워크_Day83  (0) 2015.07.10
,