gpt4 book ai didi

java - 如何处理 org.mockito.exceptions.misusing.MissingMethodInitationException?

转载 作者:行者123 更新时间:2023-12-02 03:08:33 32 4
gpt4 key购买 nike

我有一个看起来像这样的类(class)

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ClientRegistrationManager {
private CrudService crudService;
private UniqueIdGenerator uniqueIdGenerator;

@SuppressWarnings("UnusedDeclaration")
public ClientRegistrationManager() {
}

@Inject
public ClientRegistrationManager(@Nonnull final CrudService crudService, @Nonnull final UniqueIdGenerator uniqueIdGenerator) {
this.crudService = crudService;
this.uniqueIdGenerator = uniqueIdGenerator;
}

public Member register(@Nonnull final String email, @Nonnull final String userExternalId, @Nonnull final String password) {
final Member existingMember;
try {
existingMember = getMemberQueries().getMemberByEmail(email);
} catch (final NoResultException e) {
return createNewMemberAndGetClientDetail(email, userExternalId);
}
return existingMember;
}

...

@Nonnull
protected MemberQueries getMemberQueries() {
return new MemberQueries(crudService);
}
}

我想通过模拟任何外部行为来测试它,所以我创建了 getMemberQueries()使用 doc 中描述的模式 - 1

我,然后编写我的测试如下

public class ClientRegistrationManagerTest {

@Mock
private MemberQueries memberQueries;

@Mock
private CrudService crudService;

@Mock
private UniqueIdGenerator uniqueIdGenerator;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test
public void testMockedMemberQueries() {
final ClientRegistrationManager clientRegistrationManager = new ClientRegistrationManager(crudService, uniqueIdGenerator);
Mockito.when(clientRegistrationManager.getMemberQueries()).thenReturn(memberQueries);
clientRegistrationManager.getMemberQueries();
assertTrue(true);
}
}

当我运行这个时,我得到的错误为

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.

现在这意味着什么,我需要模拟整个 ClientRegistrationManager ,但是我想要测试的类,我不能只是模拟整个类。

我试图了解我的选择,我真的不想依赖 persistence层,太重了

最佳答案

Seelenvirtuose注释中是正确的:根本问题是您只能在模拟和 spy 上调用 when ,并且它通常是模拟被测类的反模式。

一种技术是使用 spy,它可以让您拦截并验证对真实对象的调用(“部分模拟”):

final ClientRegistrationManager clientRegistrationManager =
Mockito.spy(new ClientRegistrationManager(crudService, uniqueIdGenerator);
// doReturn is important because the call to contains a call to the mock
// before Mockito has intercepted it. In your case, this may just create a useless
// real MemberQueries, but in other cases it can throw an exception.
Mockito.doReturn(memberQueries).when(clientRegistrationManager).getMemberQueries();

Predrag Magic wrote ,另一种方法是创建一个工厂并在测试期间替换它。如果您将工厂作为可选构造函数参数传递,这尤其好,因为这样生产系统就可以创建并传递它们自己的 MemberQueryFactory,并且您的类仍将按预期工作。

public class ClientRegistrationManager {
static class MemberQueriesFactory {
MemberQueries getMemberQueries() {
return ObjectFactory.newMemberQueries(crudService);
}
}

/** Package-private. Visible for unit testing. */
MemberQueriesFactory memberQueriesFactory = new MembersQueryFactory();
}

@RunWith(MockitoJUnitRunner.class)
public class ClientRegistrationManagerTest {
@Mock ClientRegistrationManager.MembersQueryFactory mockMembersQueryFactory;

private ClientRegistrationManager getManagerForTest() {
ClientRegistrationManager manager = new ClientRegistrationManager();
manager.memberQueriesFactory = mockMembersQueryFactory;
return manager;
}
}

不过,我最喜欢的方法是跳过 Mockito 并直接覆盖测试中的被测类:

@RunWith(MockitoJUnitRunner.class)
public class ClientRegistrationManagerTest {
@Mock MemberQueries memberQueries;

private ClientRegistrationManager getManagerForTest() {
ClientRegistrationManager manager = new ClientRegistrationManager() {
@Override void getMemberQueries() {
return memberQueries;
}
};
}
}

关于java - 如何处理 org.mockito.exceptions.misusing.MissingMethodInitationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26609499/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com