首页 > 解决方案 > 如何解决“要创建一个新的mock,必须注销现有的mock注册”

问题描述

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

org.mockito.exceptions.base.MockitoException:对于de.msggillardon.system.UserContext,静态mock已经注册在当前线程要创建一个新的mock,现有的静态mock注册必须注销

对于以下代码:

 @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) 来模拟。

我还在网上找到了以下提示:https : //javadoc.io/static/org.mockito/mockito-core/3.4.3/org/mockito/MockedStatic.html 所以看来我必须做一个 MockedStatic.close( ); 也许作为@AfterEach 但是当我尝试时它给了我例外

无法从 ScopedMock 类型对非静态方法 close() 进行静态引用

还是行不通 :(

标签: javaunit-testingmockitojunit5

解决方案


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

  1. 步骤:导入
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
  1. 步骤:添加 @TestInstance(PER_CLASS) 注释(在您的课程之前)

  2. 步骤:@BeforeAll 而不是 @BeforeEach

这解决了我的问题。


推荐阅读