我正在为一个基于著名视频游戏的个人项目开发一个使用Spring Boot和六边形架构的简单REST API。几天前,我使用JUnit5(jupiter)和mockito编写了单元测试。他们工作得很好,但今天我更新了我的测试代码,因为我想为我的API添加i18n支持,以及一个简单的配置,允许禁用玩家和他们的官方Minecraft UUID之间的链接。
我的类的构造函数已经更改,为i18n支持添加了一个MessageSource对象,并为uuid链接状态添加了一个布尔值。我的类现在是这样的:
public class PlayerService implements PlayerApi {
private final boolean ONLINE_MODE;
private final PlayerSpi playerSpi;
private final MojangApi mojangApi;
private final MessageSource messageSource;
public PlayerService(PlayerSpi playerSpi, MojangApi mojangApi,
boolean onlineMode, MessageSource messageSource) {
this.playerSpi = playerSpi;
this.mojangApi = mojangApi;
this.ONLINE_MODE = onlineMode;
this.messageSource = messageSource;
}
@Override
public Option<Player> findByPseudoOrEmailAddress(String pseudo, String emailAddress) {
if (pseudo.isEmpty() || emailAddress.isEmpty()) return Option.none();//TODO BETTER ERROR GEST USING EITHER ?
return playerSpi.findByPseudoOrEmailAddress(pseudo, emailAddress);
}
@Override
public Option<Player> findById(Long id) {
return playerSpi.findById(id);
}
@Override
public Boolean existByPseudo(String pseudo) {
return playerSpi.existByPseudo(pseudo);
}
@Override
public Boolean existByEmailAddress(String emailAddress) {
return playerSpi.existByEmailAddress(emailAddress);
}
@Override
public void save(Player player) {
playerSpi.save(player);
}
@Override
public Response<?> register(Player player) {
//LINK PLAYER TO HIS MINECRAFT UUID IF ONLINE MODE IS TRUE
if (ONLINE_MODE) {
Either<MinecraftUUIDException, String> result = mojangApi.getPlayerUUID(player.getPseudo());
if (result.isRight())
player.setMinecraftUUID(result.get());
else
return Response.Builder.create()
.success(false)
.message(messageSource.getMessage("PlayerService.register.uuid-linking-failed",
null, LocaleContextHolder.getLocale()))
.body(result.getLeft())
.build();
}
save(player);
return Response.Builder.create()
.success(true)
.message(messageSource.getMessage("PlayerService.register.success",
null, LocaleContextHolder.getLocale()))
.body(null)
.build();
}
}
所以我创建了一个测试类,如下所示:
@ExtendWith(MockitoExtension.class)
@TestInstance(Lifecycle.PER_CLASS)
public class PlayerServiceTest {
@Mock
private PlayerSpi playerSpi;
@Mock
private MojangApi mojangApi;
@Mock
private MessageSource messageSource;
private PlayerService playerService;
@BeforeAll
void setUp() {
initMocks(this);
playerService = new PlayerService(
playerSpi,
mojangApi,
true,
messageSource
);
}
@Test
void register_should_register() {
Player p = new Player(
1L,
"Bad_Pop",
"test@test.com",
"password",
List.empty(),
"uuid"
);
when(mojangApi.getPlayerUUID(any())).thenReturn(Either.right("uuid"));
ArgumentCaptor<Player> valueCapture = ArgumentCaptor.forClass(Player.class);
lenient().doNothing().when(playerSpi).save(valueCapture.capture());
Response<?> res = playerService.register(p);
assertEquals(p.getId(), valueCapture.getValue().getId());
assertEquals(p.getPseudo(), valueCapture.getValue().getPseudo());
assertEquals(p.getEmailAddress(), valueCapture.getValue().getEmailAddress());
assertEquals(p.getPassword(), valueCapture.getValue().getPassword());
assertEquals(p.getRoles(), valueCapture.getValue().getRoles());
assertEquals(p.getMinecraftUUID(), valueCapture.getValue().getMinecraftUUID());
assertTrue(res.getSuccess());
assertTrue("Player successfully registered.".equalsIgnoreCase(res.getMessage()));
assertNull(res.getBody());
}
@Test
void register_should_not_register() {
Player p = new Player(
1L,
"Bad_Pop",
"test@test.com",
"password",
List.empty(),
"uuid"
);
when(mojangApi.getPlayerUUID(any())).thenReturn(
Either.left(
new MinecraftUUIDException("Unable to retrieve Minecraft UUID for this player. Please make sure this player name exists.")
)
);
Response<?> res = playerService.register(p);
assertFalse(res.getSuccess());
assertTrue("An error occured while registering this player".equalsIgnoreCase(res.getMessage()));
assertTrue(res.getBody().getClass().getSimpleName().equalsIgnoreCase("MinecraftUUIDException"));
MinecraftUUIDException e = (MinecraftUUIDException) res.getBody();
assertEquals("Unable to retrieve Minecraft UUID for this player. Please make sure this player name exists.",
e.getMessage());
}
//remaining tests ommitted
}
java.lang.NullPointerException
at io.denoria.domain.core.service.PlayerService.register(PlayerService.java:61)
at io.denoria.domain.PlayerServiceTest.register_should_register(PlayerServiceTest.java:178)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:139)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:81)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
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)
Suppressed: org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at io.denoria.domain.PlayerServiceTest.register_should_register(PlayerServiceTest.java:174)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:230)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$11(TestMethodTestDescriptor.java:245)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$12(TestMethodTestDescriptor.java:256)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:256)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:255)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:244)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:141)
... 41 more
我已经在其他类中添加了对i18n的支持,我没有这个问题。
initmocks()
应该在测试类的每个实例中调用,因此应该在@beforeach
方法中调用initmocks()方法中调用initmocks()。此外,@BeforeAll
需要一个静态方法--除非您已经切换了生命周期,但您的代码没有显示这一点。
我在想为什么木星不抱怨非静态方法。也许您使用的是JUnit4中的@test
?如果您不能用@beforeeach
修复这个问题,请在测试类中显示您的所有导入。
我想通过模拟class的重写方法a1方法2来测试我的服务。我不想更改课程A1和B1中的任何内容。我使用的是mockito 1.9.0和powermockito 1.4.12。我正在尝试以下代码: UnitTestService类: 服务级别: A1类: B1级: 我正在eclipse中使用testNG运行类UnitTestService。在这里,B1类a1Method2中的实际方法在控制台中打印“
问题内容: 我最近已经问了几个有关jUnit和Mockito的问题,但我仍然很努力地把握住这个问题。这些教程都是针对非常简单的示例的,因此我正在努力扩大测试用例以适合我的课程。 我目前正在尝试为Webapp中我的一个代理中的方法编写一些测试用例。该方法与代理内部的其他两种方法交互以验证某些对象。我现在只想测试这种方法。 这是我尝试做的事情: 创建我的代理的Mockito对象,如下所示: 使用Moc
我最近问了几个面向jUnit和Mockito的问题,但我仍然很难掌握其中的诀窍。这些教程都是针对非常简单的示例,所以我很难扩展我的测试用例来为我的类工作。 我目前正试图为我在WebApp中的一个代理中的一个方法编写一些测试用例。该方法与代理内部的几个其他方法交互,以验证某些对象。我现在只想测试一下这个方法。 使用Mockito设置存根(希望是正确的术语)。如下所示: 尝试执行我的方法,如下所示:
这是我的实际服务方法。在测试时,它给我的变量为空。用户和响应 我试图写一个测试用例和模拟方法findByEmail()和保存(),但同时嘲笑我没有收到用户对象在返回中提到的thenback()和doback()。 有人能帮忙吗。
我必须测试一些SLSB的方法,它在当前对象上调用另一个方法(使用这个关键字),我需要以某种方式将它存根。 请考虑以下简化代码: 为了存根getSomeDBValue()方法,我可以使用@mock和@injectMocks注释将mock注入到该类,但我不知道如何正确地存根anotherMethod()。要存根它,我需要在模拟对象上做这件事,所以我尝试将引用传递到当前对象作为参数,在测试中只传递模拟对
下面是正在测试的方法的缩短版本。 一如既往,我们感谢您能提供的任何帮助。
问题内容: 因此,我开始为我们的Java Spring项目编写测试。 我使用的是JUnit和Mockito。有人说,当我使用when()… thenReturn()选项时,可以模拟服务,而无需模拟它们。所以我要做的是设置: 但是无论我执行哪一个子句,我总会得到一个NullpointerException,这当然是有道理的,因为input为null。 另外,当我尝试从对象模拟另一个方法时: 在那里,
我试图通过在传入字符串“John”时返回一个用户对象来建立类(spring-data-jpa存储库)的方法。 发生的情况是,在userService中,当调用users.findbyUsername(“John”)时,它总是返回null,而不是我定义的任何用户对象: 当我在测试方法中放置断点并比较users和UserService.users时,它们是相等的。 pom版本