java - 如何解决 "to create a new mock, the existing mock registration must be deregistered"

标签 java unit-testing mockito junit5

尝试模拟静态方法时出现以下异常:

org.mockito.exceptions.base.MockitoException: For de.msggillardon.system.UserContext, static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered


对于以下代码:
 @ExtendWith(MockitoExtension.class)
// @PrepareForTest(UserContext.class)
public class KonfigurationCopyServiceTest {

  public static final String CONFIGURATION_NAME = "Standard-Konfiguration";

  @Mock
  public TriggeringKonfigurationService triggeringKonfigurationService;
  @Mock
  public ReportKonfigService reportConfigurationService;
  @Mock
  public BuchungsschemaService buchungsschemaService;

  public KonfigurationCopyService copyService;

  @BeforeEach
  public void init() {
    Mockito.mockStatic(UserContext.class);
    Mockito.when(UserContext.getUsername()).thenReturn("superuser");

    copyService = new KonfigurationCopyService(triggeringKonfigurationService,
        reportConfigurationService, buchungsschemaService);
  }

有人可以帮忙吗?
谢谢!
编辑:UserContext.java
package de.msggillardon.system;

/**
 * This class contains the username and IP-address of the logged in user. It is initialized for each
 * session.
 *
 * @author wildp
 */
public class UserContext {

  private static final ThreadLocal<UserContext> userContext = new ThreadLocal<>();

  private final String username;

  private final String clientIPAddress;

  /**
   * Constructor.
   *
   * @param username        Username of the user who is logged in
   * @param clientIPAddress IP Address of the user who is logged in
   */
  public UserContext(String username, String clientIPAddress) {
    this.username = username;
    this.clientIPAddress = clientIPAddress;
  }

  /**
   * Initializes the threadLocal
   *
   * @param userContext
   */
  public static void initialize(UserContext userContext) {
    UserContext.userContext.set(userContext);
  }

  /**
   * Removes the current thread's value for this thread-local variable.
   */
  public static void remove() {
    userContext.remove();
  }

  /**
   * Returns the username of the current thread.
   *
   * @return
   */
  public static String getUsername() {
    return userContext.get().username;
  }

  /**
   * Returns the IP address of the client of the current thread.
   *
   * @return
   */
  public static String getClientIPAddress() {
    return userContext.get().clientIPAddress;
  }

  public static UserContext getThreadLocalUserContext(){
    return userContext.get();
  }
}
新编辑:
我再次编辑了我的代码,以便您现在可以看到,我正在使用 @ExtendWith(MockitoExtension.lass) 进行 Mock。
我还在网上找到了以下提示:https://javadoc.io/static/org.mockito/mockito-core/3.4.3/org/mockito/MockedStatic.html
所以看起来我必须做一个 MockedStatic.close();也许作为@AfterEach
但是当我尝试时它给了我异常

Cannot make a static reference to the non-static method close() from the type ScopedMock


还是行不通 :(

最佳答案

因此,当我使用 Junit 5 时,我无法使用 @Before 注释,所以我用 @BeforeAll 替换了 @BeforeEach。
所以我做了如下:

  • 步骤:导入
  • import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
    
  • 步骤:添加 @TestInstance(PER_CLASS) 注释(在您的类(class)之前)
  • 步骤:@BeforeAll 而不是 @BeforeEach

  • 那解决了我的问题。

    关于java - 如何解决 "to create a new mock, the existing mock registration must be deregistered",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65845312/

    相关文章:

    java - IDP 在现有应用程序中启动了 SSO 实现

    java - 在kony中链接JavaConnector时发生ClascastException

    java - 如何在 Maven 中读取外部属性文件

    database - 如何使用数据库查询对对象进行单元测试

    python - 如何将 `msg` 传递给 unittest.mock 断言方法?

    java - 从 JDK 1.6 迁移到 JDK 1.7 的 PowerMockito 测试出现约束违规

    java - 使用 Mockito 的通用 "any()"方法

    java - 在另一个 jar 中运行外部 jar

    node.js - 如何测试方法回调的内容

    java - 如何注入(inject)java.io.File然后设置其名称