gpt4 book ai didi

java - 在 JUnit 测试的情况下检查类内的调用次数

转载 作者:行者123 更新时间:2023-11-29 06:53:57 25 4
gpt4 key购买 nike

我有一个计算某些东西的代码,缓存是,如果已经计算,则从缓存中读取;类似这样:

public class LengthWithCache {
private java.util.Map<String, Integer> lengthPlusOneCache = new java.util.HashMap<String, Integer>();

public int getLenghtPlusOne(String string) {
Integer cachedStringLenghtPlusOne = lengthPlusOneCache.get(string);
if (cachedStringLenghtPlusOne != null) {
return cachedStringLenghtPlusOne;
}
int stringLenghtPlusOne = determineLengthPlusOne(string);
lengthPlusOneCache.put(string, new Integer(stringLenghtPlusOne));
return stringLenghtPlusOne;
}

protected int determineLengthPlusOne(String string) {
return string.length() + 1;
}
}

我想测试函数 determineLengthPlusOne 是否被调用了足够的次数,如下所示:

public class LengthWithCacheTest {
@Test
public void testGetLenghtPlusOne() {
LengthWithCache lengthWithCache = new LengthWithCache();

assertEquals(6, lengthWithCache.getLenghtPlusOne("apple"));
// here check that determineLengthPlusOne has been called once

assertEquals(6, lengthWithCache.getLenghtPlusOne("apple"));
// here check that determineLengthPlusOne has not been called
}
}

模拟类 LengthWithCache 似乎不是一个好的选择,因为我想测试它们的功能。 (根据我的理解,我们模拟了被测试类使用的类,而不是被测试类本身。)哪个是最优雅的解决方案?

我的第一个想法是创建另一个包含函数 determineLengthPlusOne 的类 LengthPlusOneDeterminer,将其作为参数传递给函数 getLenghtPlusOne,然后模拟 LengthPlusOneDeterminer 在单元测试的情况下,但这看起来有点奇怪,因为它对工作代码有不必要的影响(类 LengthWithCache 的真实客户端)。

基本上我使用的是 Mockito,但欢迎使用任何模拟框架(或其他解决方案)!谢谢!

最佳答案

最优雅的方法是创建一个单独的类来进行缓存并用它装饰当前类(在删除缓存之后),这样您就可以安全地对缓存本身进行单元测试而不会干扰基类的功能.

public class Length {
public int getLenghtPlusOne(String string) {
int stringLenghtPlusOne = determineLengthPlusOne(string);
lengthPlusOneCache.put(string, new Integer(stringLenghtPlusOne));
return stringLenghtPlusOne;
}

protected int determineLengthPlusOne(String string) {
return string.length() + 1;
}
}

public class CachedLength extends Length {
private java.util.Map<String, Integer> lengthPlusOneCache = new java.util.HashMap<String, Integer>();

public CachedLength(Length length) {
this.length = length;
}

public int getLenghtPlusOne(String string) {
Integer cachedStringLenghtPlusOne = lengthPlusOneCache.get(string);
if (cachedStringLenghtPlusOne != null) {
return cachedStringLenghtPlusOne;
}
return length.getLenghtPlusOne(string);
}
}

然后你可以很容易地测试缓存我注入(inject)一个模拟的Length:

Length length = Mockito.mock(Length.class);
CachedLength cached = new CachedLength(length);
....
Mockito.verify(length, Mockito.times(5)).getLenghtPlusOne(Mockito.anyInt());

关于java - 在 JUnit 测试的情况下检查类内的调用次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38555209/

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