guava_使用Guava进行测试集合的实现

news/2024/7/19 14:48:21 标签: java, python, spring, js, spring boot
guava

guava

我目前正在为LibFX添加一项新功能,为此我创建了一些类似于Java Collections Framework中的自定义集合的自定义集合。 我一直在寻找可以与之对抗的测试,并很高兴地发现Google的Guava包含了我所需要的:一个庞大的测试套件,它针对JDK和Guava的所有集合接口验证了我实现的每个细节。

让我们快速浏览一下。

总览

这篇文章将首先展示如何设置项目,然后再着手进行实际测试。

我没有创建专门的示例,但是您可以看到我如何在LibFX中使用它。

设定

为此,我们需要JUnit,Guava-Testlib和一些样板代码。

获取JUnit

如果您尚未在项目中使用JUnit,请在此处获取。 如果您使用Maven或Gradle:

Maven的依赖项信息

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>

Gradle的依赖项信息

java">testCompile 'junit:junit:4.12'

获取番石榴

我们实际上需要的不是Guava本身,而是Guava-Testlib 。 您可以从中央存储库下载它, 该存储库还包含不同管理者的依赖项信息。

为了您的方便:

Maven的依赖项信息

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava-testlib</artifactId>
	<version>18.0</version>
	<scope>test</scope>
</dependency>

Gradle的依赖项信息

java">testCompile 'com.google.guava:guava-testlib:18.0'

写一些样板

假设您要编写一个MySet和相应的MySetTest

通过JUnit-3.8.x方式,创建一个方法public static Test suite();. JUnit查找此方法,并使用它来识别将为该类运行的所有测试。 在该方法内,创建一个TestSuite并添加我们将进一步编写的测试:

MySetTest中的样板

java">public class MySetTest {

	public static Test suite() {
		return new MySetTest().allTests();
	}

	public Test allTests() {
		TestSuite suite =
			new TestSuite("package.name.of.MySetTest");
		suite.addTest(testForOneToWayUseMySet());
		suite.addTest(testForAnotherWayToUseMySet());
		return suite;
	}
	
}

(我没有尝试使用JUnit 4的注释来做到这一点。

放置好样板后,您可以使用JUnit运行此类,例如,从IDE内部或CI服务器上运行此类。

测试您的实施

至此,我们可以开始为实现实际创建测试了。 或者,更准确地说,告诉番石榴如何为我们做到这一点。 这是一个分为两部分的过程:一个为集合中的元素和被测单元创建一个生成器,另一个使用Guava的测试套件构建器之一来创建针对实现量身定制的全面测试集。

我们将继续测试Set的实现。 在下面,我们将看到可用的其他接口测试套件。

元素生成器和被测单元

测试套件生成器要求您允许在集合中创建样本元素并实例化集合。 为此,您必须实现TestSetGenerator<E> (其中E是元素的类型)。

这很简单, order(List<E>)是可能需要考虑的唯一方法。 请注意,与文档相反,即使未报告CollectionFeature.KNOWN_ORDER ,testlib(18.0)的当前版本也确实调用了此方法(有关功能的详细信息,请参见下文)。 就我而言,返回插入顺序就足够了。

测试套件生成器

现在,这才是真正的魔术发生。 您从上方获取生成器,将其传递给正确的测试套件生成器,指定您的集合具有哪些功能,它将创建定制的全面测试套件:

使用“ SetTestSuiteBuilder”创建测试

java">public Test testForOneToWayUseMySet() {
	return SetTestSuiteBuilder
			.using(new MySetGenerator())
			.named("one way to use MySet")
			.withFeatures(
					CollectionSize.ANY,
					CollectionFeature.ALLOWS_NULL_VALUES,
					CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
					CollectionFeature.SUPPORTS_ADD,
					CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
					CollectionFeature.SUPPORTS_REMOVE,
			)
			.createTestSuite();
}

特征

指定正确的功能很重要。 查看两个枚举CollectionSizeCollectionFeatures以查看存在哪些可能性来描述集合的行为。

请注意,创建的测试会同时验证功能! 例如,如果ALLOWS_NULL_VALUES ,构建器将生成测试,以验证向集合添加null会抛出NullPointerException

抑制测试

通过在构建器上调用suppressing ,您可以指定将不会运行的测试方法。 当这些功能不足以精确指定行为时,它似乎是最后的选择。 我没有使用它。

设置与拆卸

如果必须在每次测试之前或之后运行代码,则可以将其作为Runnable分别withTearDownwithSetUpwithTearDown (都可以在构建器上调用)。

可用的测试套件

当然,您也可以为其他接口生成测试套件。 乍一看就产生了以下可能性:

Java的集合:

  • 采集
  • 迭代器
  • 清单
  • 地图
  • 导航地图
  • 导航集
  • 队列
  • SortedMap
  • SortedSet

番石榴的收藏:

  • 双图
  • ListMultimap
  • 多图
  • 多集
  • SetMultimap
  • SortedMultiset
  • SortedSetMultimap

* TestSuiteBuilder进行类型搜索(请注意通配符)会产生一些其他生成器。 我没有对其进行调查,但是有可能将其用于其他情况下的测试。

为了使用它们,只需实现相应的Test...Generator并将其交给相应的...TestSuiteBuilder

反射

我们已经看到了如何使用Guava的Testlib测试集合的实现:如何将其和JUnit包含在我们的项目中,我们需要使其运行的样板文件以及生成器和测试套件生成器的概述。 后者是发生所有魔术的地方,它可以创建全面的测试,以适合我们对实现及其功能的描述。

翻译自: https://www.javacodegeeks.com/2015/03/test-collection-implementations-with-guava.html

guava


http://www.niftyadmin.cn/n/1707776.html

相关文章

pdf可不可以批量命名_不可将您的方法命名为“等于”

pdf可不可以批量命名(当然&#xff0c;除非您确实重写了Object.equals() )。 我偶然发现了用户Frank的一个非常奇怪的Stack Overflow问题&#xff1a; 为什么Java的Area&#xff03;equals方法不能覆盖Object&#xff03;equals&#xff1f;有趣的是&#xff0c;有一个Area.equ…

2019年Java常见面试问题

文章目录一.JAVAJava中8大基本类型占用的字节数?和equals的区别是什么?final在java中有什么作用?java容器有哪些?HashMap和Hashtable有什么区别?HashMap的实现原理?ArrayList和LinkedList的区别是什么?sleep()和wait()有什么区别?在java程序中怎么保证多线程的运行安全…

full gc_在运行时打开GC日志记录

full gc总是有下一个JVM表现不佳。 而且&#xff0c;您内心深知&#xff0c;如果您只有少数启动选项可以揭示有关正在发生的事情的更多信息&#xff0c;则您可能有机会真正修复该死的东西。 但是不&#xff0c;您需要的标志( -XX&#xff1a; HeapDumpOnOutOfMemoryError或-XX&…

java基础总结大全

文章目录一、基础知识&#xff1a;1、JVM、JRE和JDK的区别&#xff1a;2、环境变量path和classpath的作用是什么&#xff1f;3、变量有什么用&#xff1f;为什么要定义变量&#xff1f;什么时候用&#xff1f;4、&和&&的区别?5、标示符命名规则6、数据类型&#x…

oauth2_教程:如何实现Java OAuth 2.0以使用GitHub和Google登录

oauth2将Google和GitHub OAuth登录添加到Java应用程序的指南 我们添加到Takipi的最新功能之一是3rd party登录。 如果您像我一样懒惰&#xff0c;那么我想您也希望跳过填写表单和输入新密码的操作。 只要有权限&#xff0c;许多人都希望使用第三方登录&#xff0c;只要他们要求…

EXTJS学习笔记

sencha which set PATH%PATH%;C:\Sencha\Cmd\6.0.0.92 sencha generate app --ext MyApp ./myapp 将会创建名为 MyApp 的 Ext JS 应用&#xff0c;应用所有的文件都放在 当前目录下名为 myapp 的文件夹。 extjs 1.基本结构: Ext.define(‘Car’,{ name:null, constructor:…

输入捕获_企业应用程序中要捕获的5大Java性能指标

输入捕获有兴趣了解如何使用AppDynamics捕获这些Java性能指标吗&#xff1f; 立即开始免费试用&#xff01; 最后几篇文章介绍了应用程序性能管理(APM)&#xff0c;并指出了有效实施APM战略的挑战。 本文通过回顾五个顶级性能指标来构建这些主题&#xff0c;以评估您的企业Java…

lambda表达式_Lambdas中的例外:有点混乱的优雅解决方案

lambda表达式考虑以下用于写入文件的功能&#xff1a; 该方法背后的想法是&#xff0c;以允许用户在不同的实施方式中通过InputStream的方法&#xff0c;以便writeToFile可以被称为例如用GZIPOuputStream &#xff0c; SnappyOuputStream(快速压缩)或简单的FileInputStream 。 …