반응형
아래와 같이 간단한 클래스가 있다고 가정해보자.
package com.example.mockedstaticunittest;
public class Calculator {
public static int add(int x, int y) {
return x + y;
}
public int sub(int x, int y) {
return x - y;
}
}
해당 코드의 sub를 테스트를 하면 아래와 같다.
@Test
public void execute_sub() {
Calculator calculator = new Calculator();
// when
int sub = calculator.sub(20, 10);
// then
assertEquals(sub, 10);
}
Process finished with exit code 0
하지만 static인 add를 테스트 하면 아래와 같아진다.
@Test
public void execute_add() {
int a = 1, b = 2;
when(Calculator.add(a, b)).thenReturn(a + b);
int sum = Calculator.add(a, b);
assertEquals(a + b, sum);
}
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
at com.example.mockedstaticunittest.CalculatorTest.execute_add(CalculatorTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
static 메서드를 테스트 할 수 없는 상황이 왔고 이를 해결하기 위해 이번에는 Mockito를 이용하여 static method를 해결하는 방법을 알아보고자 한다.
asolntsev.github.io/en/2020/07/11/mockito-static-methods/
우선 build.gradle에서 dependency에 testImplementation('org.mockito:mockito-inline:3.4.0')를 추가해준다.
3.4.0버전부터 MockedStatic라는 새로운 기능이 들어감으로써 우리는 PowerMock가 아닌 Mockito를 이용하여서도 static method를 테스트할 수 있게 되었다.
아래와 같이 MockedStatic객체를 선언한다.
private static MockedStatic<Calculator> mCalculator;
그리고 해당 MockedStatic를 mockStatic 메서드를 이용하여 beforeClass에서 모킹하고 afterClass에서 해제해준다.
@BeforeClass
public static void beforeClass() {
mCalculator = mockStatic(Calculator.class);
}
@AfterClass
public static void afterClass() {
mCalculator.close();
}
다시 static add method를 테스트해준다. 이때 Calculator.add(anyInt(), anyInt()).thenReturn(a+b)을 이용하여 해당 static method를 모킹해주면 이제 해당 스태틱 메서드를 사용할 수 있게 된다.
@Test
public void execute_add() {
int a = 1, b = 2;
when(Calculator.add(anyInt(), anyInt())).thenReturn(a + b);
int sum = Calculator.add(a, b);
assertEquals(a + b, sum);
}
아래는 전체 코드이다.
package com.example.mockedstaticunittest;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.MockedStatic;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class CalculatorTest {
private static MockedStatic<Calculator> mCalculator;
@BeforeClass
public static void beforeClass() {
mCalculator = mockStatic(Calculator.class);
}
@AfterClass
public static void afterClass() {
mCalculator.close();
}
@Test
public void execute_add() {
int a = 1, b = 2;
when(Calculator.add(anyInt(), anyInt())).thenReturn(a + b);
int sum = Calculator.add(a, b);
assertEquals(a + b, sum);
}
}
반응형
'Basic > Android' 카테고리의 다른 글
Android에서 chips를 사용하는 방법 (0) | 2021.03.29 |
---|---|
ColorStateList 사용 예제 (0) | 2021.03.29 |
[Android] 리사이클러뷰 생성 예제 (1) | 2020.10.12 |
Android 파일 대소문자 구분 (Case sensitivity) (0) | 2020.08.27 |
Volley와 Gson을 이용하여 리퀘스트 및 파싱 예제 (0) | 2020.08.24 |