JUnit:模拟在另一个方法中调用的方法
JUnit: mock a method called inside another method
假设我有一个 class Tournament
,方法是 register()
和 isAlreadyRegistered()
。下面是示例代码。
public class Tournament {
private boolean register(String teamName) {
if(!isAlreadyRegistered(teamName)) {
// register team
return True;
}
return False;
}
private boolean isAlreadyRegistered(String teamName) {
// Check if team is already registered, involves DB calls
}
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
tournament.register("e-LEMON-ators");
}
}
我有一个 Java 测试用例,它调用 class Tournament
的主要方法,这导致调用
register()
方法和 register()
方法调用 isAlreadyRegistered()
。考虑以下代码:
@Test
public void testTournament() {
try {
Tournament.main(args);
} catch (Exception e) {
fail();
}
}
我想模拟 isAlreadyRegistered()
,也许使用 Mockito,所以它总是 returns True
注意:该示例仅用于演示目的,我无法修改锦标赛class。修改只能在测试用例中进行。单独测试 register()
不是一个选项(调用必须通过 main 方法进行)
编辑: 我无法为 class Tournament
创建对象,即我只能通过 main()
与 class 交互方法
尝试将实际的注册方法调用移动到不同的方法中,以便您可以将锦标赛实例传递给该方法。这意味着,将您的主要方法修改为
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
performRegister(tournament);
}
public static void performRegister(Tournament tournament) {
tournament.register("e-LEMON-ators");
}
现在你的测试方法变成如下。
@Test
public void testTournament() {
try {
Tournament tournament = Mockito.mock(Tournament.class);
Mockito.when(tournament.isAlreadyRegistered(anyString())).thenReturn(true);
Tournament.performRegister(tournament);
} catch (Exception e) {
fail();
}
}
编辑:
另一种解决方案是,如果您不想修改 Tournament
class,请使用 PowerMock
.
这里是测试class
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Tournament.class)
public class TournamentTest {
@Test
public void testTournament() {
try {
Tournament mock = PowerMockito.mock(Tournament.class);
PowerMockito.when(mock.isAlreadyRegistered(anyString())).thenReturn(true);
PowerMockito.whenNew(Tournament.class).withAnyArguments().thenReturn(mock);
Tournament.main(null);
} catch (Exception e) {
fail();
}
}
}
这里是依赖项
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
这里是参考文件
Tournament.java
: https://gist.github.com/sjabiulla/4bdf71f81079e38aef137e64913bf26b
TournamentTest.java
: https://gist.github.com/sjabiulla/4a557516e834bba6d6047687f7e32deb
pom.xml
: https://gist.github.com/sjabiulla/10abb153e82e14194fd1ccc2689b192d
假设我有一个 class Tournament
,方法是 register()
和 isAlreadyRegistered()
。下面是示例代码。
public class Tournament {
private boolean register(String teamName) {
if(!isAlreadyRegistered(teamName)) {
// register team
return True;
}
return False;
}
private boolean isAlreadyRegistered(String teamName) {
// Check if team is already registered, involves DB calls
}
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
tournament.register("e-LEMON-ators");
}
}
我有一个 Java 测试用例,它调用 class Tournament
的主要方法,这导致调用
register()
方法和 register()
方法调用 isAlreadyRegistered()
。考虑以下代码:
@Test
public void testTournament() {
try {
Tournament.main(args);
} catch (Exception e) {
fail();
}
}
我想模拟 isAlreadyRegistered()
,也许使用 Mockito,所以它总是 returns True
注意:该示例仅用于演示目的,我无法修改锦标赛class。修改只能在测试用例中进行。单独测试 register()
不是一个选项(调用必须通过 main 方法进行)
编辑: 我无法为 class Tournament
创建对象,即我只能通过 main()
与 class 交互方法
尝试将实际的注册方法调用移动到不同的方法中,以便您可以将锦标赛实例传递给该方法。这意味着,将您的主要方法修改为
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
performRegister(tournament);
}
public static void performRegister(Tournament tournament) {
tournament.register("e-LEMON-ators");
}
现在你的测试方法变成如下。
@Test
public void testTournament() {
try {
Tournament tournament = Mockito.mock(Tournament.class);
Mockito.when(tournament.isAlreadyRegistered(anyString())).thenReturn(true);
Tournament.performRegister(tournament);
} catch (Exception e) {
fail();
}
}
编辑:
另一种解决方案是,如果您不想修改 Tournament
class,请使用 PowerMock
.
这里是测试class
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Tournament.class)
public class TournamentTest {
@Test
public void testTournament() {
try {
Tournament mock = PowerMockito.mock(Tournament.class);
PowerMockito.when(mock.isAlreadyRegistered(anyString())).thenReturn(true);
PowerMockito.whenNew(Tournament.class).withAnyArguments().thenReturn(mock);
Tournament.main(null);
} catch (Exception e) {
fail();
}
}
}
这里是依赖项
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
这里是参考文件
Tournament.java
: https://gist.github.com/sjabiulla/4bdf71f81079e38aef137e64913bf26b
TournamentTest.java
: https://gist.github.com/sjabiulla/4a557516e834bba6d6047687f7e32deb
pom.xml
: https://gist.github.com/sjabiulla/10abb153e82e14194fd1ccc2689b192d