gpt4 book ai didi

java - 我可以在使用 Mockito 模拟方法时忽略它的方面吗?

转载 作者:行者123 更新时间:2023-11-30 11:15:22 25 4
gpt4 key购买 nike

我有一个类,其中包含一些通过输入验证方面建议的方法(验证所有输入参数是否为非空/非空字符串)。

我在为他们编写测试用例时遇到问题,想验证这是否确实是一个糟糕的设计问题。

这是我的类(class)的一个非常简化的版本:

public class A {

public String one(String word) {
// Some actions
String val = two(word2);
// Some more actions
}

protected String two(String word) {
// Some actions
}

}

现在,在为 one() 编写测试用例时,我使用 Mockito 并希望模拟对 two() 的调用。所以我使用:

@Spy
A a;

@Test
void test() {
doReturn("Bye").when(A).two(Mockito.anyString());

a.one("hello");
// Some validations
}

此测试失败,因为:doReturn() 行失败,two() 的输入为空。

我不应该模拟 two() 还是我可以以某种方式让它工作?

编辑:
根据要求添加与两个不同类中存在的两种方法相关的更具体示例:

通过 WebService 创建页面。这会构建一个 putRequest,执行它并返回一个响应。

public class AUtility implements BaseUtility {
public Response create(Params params) {

try {
PutMethod putRequest = buildPUTRequest(params.getAttr1(), params.getAttr2());
return Utils.buildResponse(client.executeMethod(putRequest),
params.getAttr3(),
params.getAttr4());
} catch (Exception e) {
throw new AppException(e);
}
}
}

put 请求将数据编码到文件中以通过 HttpClient 写入

private PutMethod buildPUTRequest(final String url, final Object obj) throws IOException, JAXBException {

// Create a temp file to store the stream
File tempFile = File.createTempFile(APPLICATION_LABEL, XML_LABEL);
decoder.marshal(obj, tempFile);

// Build the put method

return putMethod;
}

XML 编码器

public interface XMLDecoder implement Decoder {

public void marshal(Object obj, File tempFile) throws IOException, JAXBException {
// Perform marshalling operations
}
}

第 2 行测试失败,输入为空。

@Test
public void createPageParamsHttpException() throws HttpException, IOException, JAXBException {
expectedException.expect(AppException.class);
doNothing().when(decoder).marshal(Mockito.anyString(), Mockito.any(File.class));
doThrow(HttpException.class).when(client).executeMethod(Mockito.any(HttpMethod.class));

Params params = new Params(new Application(),
APPLICATION_URL_LABEL,
SITE_NAME_LABEL,
URL_WITHOUT_HTTP_N_HTML);

utility.createPage(params);
}

知道我应该如何进行吗?

最佳答案

你不想这样做。

您本质上是在改变类的行为。如果您更改 two() 的功能,您怎么知道 one() 会执行它在生产中应该执行的操作?

如果你真的想这样做,你应该将 two() 的行为提取到另一个顶级类中,然后将依赖项注入(inject)到 A 中。然后您可以模拟此依赖关系,而不必担心为 A 创建部分模拟的麻烦。

以类似的方式,如果您必须将 two 保留在同一个类中(因为它的行为是分配给 A 的相同职责的一部分 - 请参阅 Single Responsibility Principle - 为什么它是public


您遇到麻烦的原因是您违反了 SRP,请参阅我上面的说明。你是这样说的:

This builds a putRequest, executes it and returns a response.

您不应该尝试同时测试这三样东西的行为。最终,这个方法并没有真正做任何事情。 buildPUTRequest 方法可以,而且不应该在名为 AUtility 的类中,它应该在类 RequestFactory 中。然后,你会想要测试 Utils.buildResponse 方法,除了它不应该在一个名为 Utils 的类中,它应该在一个名为 Responder 的类中 之类的...而且这个方法绝对不应该是 static

努力为您的类命名更好的东西,如果您不能想出一个好名字,这意味着该类可能做的太多了,应该重构。并且将工作包装在其他两个方法中的方法不需要进行单元测试。也许已经过集成测试,但那是另一回事了。

关于java - 我可以在使用 Mockito 模拟方法时忽略它的方面吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25453125/

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