Android 공부/단위테스트 관련

JUnit4 함수.

Machine_웅 2022. 5. 13. 20:07
728x90
반응형

https://junit.org/junit4/

 

JUnit – About

JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks. @Test public void newArrayListsHaveNoElements() { assertThat(new ArrayList ().size(), is(0)); } @Test public void sizeReturnsNum

junit.org

 

 

Junit4 애노테이션

@BeforeClass : 테스트 클래스 내에서 수행 전 한 번만 실행, static method 여야 함
@AfterClass : 테스트 클래스 내에서 수행 후 한 번만 실행, static method 여야 함
@Before : 테스트 케이스 수행 전 반복실행
@After : 테스트 케이스 수행 후 반복실행
@Test : 테스트 메소드 지정

@Test
: 메소드 위에 해당 어노테이션을 선언해, 테스트 대상 메소드임을 지정할 수 있다

 

.@Test(timeout=밀리초)
: 테스트 메소드 수행 시간을 제한할 수 있다.
테스트메소드가 리턴값을 반환하는 데에 걸리는 시간이 지정된 밀리초를 넘긴다면 해당 테스트는 실패로 판별한다.

 

@Test(expected=예외)
: 해당 테스트 메소드 예외 발생 여부에 따라 성공/실패를 판별할 수 있다.
expected=에 지정된 예외가 발생해야 테스트가 성공한 것으로 판별한다.

 

@Ignore
: 해당 어노테이션이 선언된 테스트 메소드를 실행하지 않도록 지정한다.

 

@BeforeEach == (구)@Before
: 모든 @Test메소드가 실행되기 전에 실행되는 메소드를 지정하는 어노테이션이다.

각 테스트 시작 전에 각각 호출된다.

@Test메서드에서 공통으로 사용되는 코드를 @Before메서드에 선언해 사용하면 좋다.

테스트마다 공통으로 쓰이면서, 테스트 전에 리셋되어야 할 항목이 들어간다

 

@AfterEach == (구)@After
: 모든 @Test메소드의 실행이 끝난 뒤에 실행되는 메소드를 지정하는 어노테이션이다.

각 테스트가 끝나고 각각 호출된다.

 

@BeforeAll == (구)@BeforeClass
: 해당 테스트 클래스가 실행될 때 딱 한 번만 수행되는 테스트 메소드를 지정하는 어노테이션이다.

 

@AfterAll == (구)@AfterClass
: 해당 테스트 클래스가 실행이 끝난 뒤에 딱 한 번만 수행되는 테스트 메소드를 지정하는 어노테이션이다.

테스트클래스의 모든 테스트가 완료된 뒤 한 번 호출된다.

 

함수

import static org.junit.Assert.*; 으로 static import 하여 쉽게 사용할 수 있음.

두 값이 같은 지 비교 

assertEquals([message], expected, actual)

 

두 객체가 동일한 객체인지 비교

ssertSame([message], expceted, actual)
assertNotSame([message], expceted, actual)

 

참/거짓 판별

assertTrue([message], expceted)
assertFalse([message], expceted)

 

null여부 판단

assertNull([message], expceted)
assertNotNull([message], expceted)

 

테스트 실패로 판단

fail([message]) 


 

 

Live Data 관련 테스트

 

LiveDataTestUtil.kt 

package com.woong.wstudy.junitMokito

import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException

    // JUnit Test 관련  Live Data 변화 감지
    //  https://lagojin.github.io/livedata-test/
    fun <T> LiveData<T>.getOrAwaitValue(time: Long = 2, timeUnit: TimeUnit = TimeUnit.SECONDS): T {
        var data: T? = null

        val latch = CountDownLatch(1)

        val observer = object : Observer<T> {
            override fun onChanged(o: T?) {
                data = o
                latch.countDown()
                this@getOrAwaitValue.removeObserver(this)
            }
        }

        this.observeForever(observer)

        // Don't wait indefinitely if the LiveData is not set.
        if (!latch.await(time, timeUnit)) {
            throw TimeoutException("LiveData value was never set.")
        }

        @Suppress("UNCHECKED_CAST")
        return data as T
    }

 

Test Code

    @Test
    fun test02_LiveData_Change(){
        // 간단하게 사용 하는 방법 temp.resultLiveData.observeForever{}
        System.out.println("test02_LiveData_Change \n\n")

        var temp  = Vm_JMMain()
        temp.setData(11)
        temp.resultLiveData.observeForever{}
        assertEquals(temp.resultLiveData.value,11)


        // LiveDataTestUtil을 만들어서 사용하는 방법
        // https://lagojin.github.io/livedata-test/

        temp.setData(12)
        assertEquals(temp.resultLiveData.getOrAwaitValue(), 12)

        assertEquals(temp.changeValueTest().getOrAwaitValue(), 20)
    }

 

 

VM Code

class Vm_JMMain : ViewModel(){

    private var _resultLiveData = MutableLiveData<Int>()
    var resultLiveData: LiveData<Int> = _resultLiveData

    private var _resultLiveString = MutableLiveData<String>()
    var resultLiveString: LiveData<String> = _resultLiveString

    var testMsg = "Start"

    fun vm_MyValidation(value : Int) : mStatsResult{
        var resultMessage = ""
        if(value < 10){
            resultMessage ="10보다 큰 숫자를 입력해주세요."
        }else {
            resultMessage ="성공"
            _resultLiveData.value = value
            _resultLiveString.value = resultMessage
        }
        return mStatsResult(resultMessage,value)
    }

    fun setData(value: Int){
        _resultLiveData.value = value
    }

    fun getData(): String{
        return ""
    }

    fun changeValueTest() : LiveData<Int>{
        _resultLiveData.value = 20
        return resultLiveData
    }


    data class mStatsResult(val message: String, val value: Int)

}
728x90
반응형