java - 如何解决 "arguments are different"错误 - 单元测试

标签 java junit mockito

我想用mockito为我的addTask方法编写单元测试。 这是包含此方法的类。

package controller;

import model.Task;
import model.User;
import repository.TaskActions;
import repository.UserActions;

import java.sql.SQLException;
import java.util.List;

public class ToDoEngine {
private TaskActions taskActions;
private UserActions userActions;
private User connectedUser;

public ToDoEngine(UserActions userStorage, TaskActions taskStorage) {
    this.taskActions = taskStorage;
    this.userActions = userStorage;
}

public boolean signIn(String username, String password) throws SQLException {
    connectedUser = new User(username, password);
    if (!userActions.signIn(connectedUser)) {
        return false;
    }
    connectedUser.setID(retrieveConnectedUserID(connectedUser));
    return true;
}

private int retrieveConnectedUserID(User connectedUser) throws SQLException {
    return userActions.retrieveUserID(connectedUser);
}

public void addTask(String taskName) throws SQLException {
    taskActions.addTask(new Task(taskName), connectedUser);
}

}

这是我的尝试。不幸的是,我有错误。下面,我将向您展示堆栈跟踪:

package controller;

import model.Task;
import model.User;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import repository.TaskActions;
import repository.UserActions;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class ToDoEngineTest {

@Mock
TaskActions taskActionsMock;
@Mock
UserActions userActionsMock;
private ToDoEngine toDoEngine;


@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    toDoEngine = new ToDoEngine(userActionsMock, taskActionsMock);
}

@Test
public void addTask() throws SQLException {
    Task taskName = new Task("wash");
    User user = new User("admin","123");
    toDoEngine.addTask("wash");
    verify(taskActionsMock).addTask(taskName,user);
}
}

堆栈跟踪:

Argument(s) are different! Wanted:
taskActionsMock.addTask(
    Task(taskName=wash),
    model.User@1b71f500
);
-> at controller.ToDoEngineTest.addTask(ToDoEngineTest.java:68)
Actual invocation has different arguments:
taskActionsMock.addTask(
    Task(taskName=wash),
    null
);
-> at controller.ToDoEngine.addTask(ToDoEngine.java:40)

Comparison Failure:  <Click to see difference>

Argument(s) are different! Wanted:
taskActionsMock.addTask(
    Task(taskName=wash),
    model.User@1b71f500
);
-> at controller.ToDoEngineTest.addTask(ToDoEngineTest.java:68)
Actual invocation has different arguments:
taskActionsMock.addTask(
    Task(taskName=wash),
    null
);
-> at controller.ToDoEngine.addTask(ToDoEngine.java:40)
at controller.ToDoEngineTest.addTask(ToDoEngineTest.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...

User 和 Task 类包含 hashCode 和 Equals 方法。

任务

package model;

import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@ToString
@NoArgsConstructor
@EqualsAndHashCode
public class Task {
private String taskName;
}

用户:

package model;

import lombok.*;

@RequiredArgsConstructor
@Getter
@Setter
@EqualsAndHashCode

public class User {

private final String name;
private final String password;
private int ID;
}

预先感谢您的帮助。 :D

最佳答案

在您的测试用例中,您尝试验证对此方法的调用:

public void addTask(String taskName) throws SQLException {
    taskActions.addTask(new Task(taskName), connectedUser);
}

这样:

User user = new User("admin","123");
...
verify(taskActionsMock).addTask(taskName,user);

失败消息...

Actual invocation has different arguments:
taskActionsMock.addTask(
    Task(taskName=wash),
    null
);

...告诉我们测试调用中connectedUser的值为null

查看您的代码,ToDoEngineconnectedUser 成员是通过调用 signIn() 方法填充的,但您的测试用例不是调用该方法,因此当您的测试调用 addTask 时,connectedUser 为 null。

因此,如果您不需要/想要测试是否向 addTask 提供了正确的用户,则只需将验证调用更改为:verify(taskActionsMock).addTask(taskName,空)

但是,这感觉像是一种回避,因此您应该确保 connectedUser 不为 null,并且是您在测试用例中提供给验证调用的值。

关于java - 如何解决 "arguments are different"错误 - 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52205905/

相关文章:

java - 如何使用 JakeWharton 的 DiskLruCache 正确读写数据?

java - 用于单元测试的模拟 Spring Controller

java - 如何使用 Mockito 模拟 System.getProperty

java - 如何在 spring mvc 中将 LIST 从一个 Controller 传递到另一个 Controller

java - 如何使用java解析XML文件

java - 使用 Junit + Eclipse 将数据保留在本地存储谷歌应用程序引擎中

android - clickView如何正确使用?

testing - Vertx 使用 Handler<AsyncResult<>> 参数模拟一个异步方法

java - 为java http客户端编写Mock类

java - 在 Java 中从二进制转换回其字符串值