Generate a Test Class for a Java Class
Select Squaretest | Generate Test (Alt+Insert+Generate Test) to generate a test class in either Java 8+ or Groovy. More...The Generated Test Class Contains Appropriate Boilerplate Code
Squaretest automatically generates the following based on your source class:- Code to construct the source class and initialize its dependencies, when appropriate
- A test method for each public and package-local method in the source class,
containing
- Code to initialize arguments required by the method
- Mockito stubs like when() and doAnswer() statements
- Code to invoke the method
- An assertEquals() call or Groovy assertion statement
- Mockito verify() statements
- Code to initialize data transfer objects (DTOs) used in the above
- Test methods for alternate flows, including cases where:
- Dependency methods throw exceptions
- Dependency methods return either null or absent values like Optional.empty()
- Dependency methods return empty values like Collections.emptyList()
- Dependency methods return failure values like CompletableFuture.failedFuture(..)
- Dependency methods return broken I/O values like new BrokenInputStream()
- Dependency methods return empty I/O values like InputStream.nullInputStream()
- Method parameters contain broken I/O values like new BrokenInputStream()
Choose Which Dependencies Should Be Mocked
Select Squaretest | Generate Test - Confirm Options (Alt+Insert+Generate Test - Confirm Options) to choose the following options before creating the test class:- Which dependencies should be mocked
- Which methods should be tested
- Whether to construct the source class in a setup method or in each test method.
Uses Dataflow Analysis and Control Flow Analysis
Squaretest uses dataflow analysis and control flow analysis to generate as much of the tests as it can. In many cases developers only need to fill in the details in order to complete the tests. For example change the placeholder values, add assertions, etc.Reads the Javadocs
Squaretest reads the Javadocs for the dependency methods the source class interacts with. This enables Squaretest to create tests for cases where:- The dependency methods throw the exceptions declared in the @throws tags
- The dependency methods return null, in some cases
- Squaretest looks for annotations indicating that a method can return null.
- Squaretest uses very basic Natural Language Processing (NLP) to determine if the Javadocs indicate a method can return null.
Use a Velocity Template to Configure How the Test Classes Are Generated
All aspects of the generated test classes are determined by an Apache Velocity template. You can use one of the default templates included with Squaretest or create your own template. More...Includes Default Velocity Templates for Common Test Frameworks
Squaretest includes default Velocity templates for both Java and Groovy for the following test frameworks and mocking frameworks.- JUnit4 with Mockito
- JUnit4 with Mockito and AssertJ
- JUnit4 with Spring and Mockito
- JUnit4 with Spring, Mockito and AssertJ
- JUnit5 with Mockito
- JUnit5 with Mockito and AssertJ
- JUnit5 with Spring and Mockito
- JUnit5 with Spring, Mockito and AssertJ
- TestNG with Mockito
- Robolectric3+ with Mockito
- AndroidJUnit4 with Mockito
Detects Design Patterns in the Source Class
All templates included with Squaretest handle the following design patterns in the source class.- The standard Java component with dependencies provided in the constructor
- Components with private fields annotated with @Inject, @Autowired or similar annotations
- Components with package-local fields annotated with @Inject or similar annotations.
- Components with dependencies provided via setter methods
- Classes with static factory methods like parse(..) or from(..) but no package-visible constructor; i.e. the sealed abstract class and similar patterns
- Abstract classes in general
- Classes containing only static methods; e.g. the Utils classes
- Traditional Singletons
- Enum Singletons
- Enums in general
- Android activities (Robolectric3 and AndroidJUnit4 templates only, limited support)
- Spring controllers (Spring templates only)
- More Examples...
Initializes Data Transfer Objects
Squaretest initializes data transfer objects (DTOs) returned by dependency methods as well as those used in method parameters. Squaretest recursively initializes DTOs that use the following patterns.- Classes with data provided via the constructor
- Classes with data provided via lombok builder methods
- Beans with data provided via setter methods
- JAXB beans with list properties (where data is provided by adding items to the list returned by the corresponding getter method)
- Classes generated by Protobuf-3
- Request and Response classes used in the AWS SDK V1 and V2
- Classes initialized by calling static factory methods like from(..) or of(..)
Generates Code Based on Dependency Method Return Values
Squaretest generates code based on the values returned by dependency methods the source methods interact with. This includes the following.- Verify statements to ensure Closeables returned by dependency methods are closed
- Alternate flow tests for some AWS SDK APIs that return absent or empty values
- Alternate flow tests for dependency methods that return objects containing I/O values; e.g. the AWS SDK S3 APIs for retrieving objects
Default Templates Contain Quick Settings
All templates included with Squaretest have Quick Settings, or variables set at the top of the file that can be used to set code style and other settings. The Quick Settings include the following options.- Use special prefixes for test class members containing dependencies and/or mocks
- Use special prefixes for local variables containing test method parameters and/or mocks
- Customize the name of the member or local field used to store the instance of the source class
- Use the JUnit5 Mockito Extension, the JUnit4 Mockito Runner or the TestNG Mockito Listener
- Use Mockito BDD
- Use static imports for openMocks and related methods
- Set the maximum number of bean setter methods that will be called when initializing a data object
- Use custom initialization expressions for dependencies and test method arguments of certain types
- More...
Default Values for Common Types
Squaretest uses default values for commonly-used types that developers don't usually mock; e.g. dependencies and local variables of type List will be set to either Arrays.asList(..) or List.of(..). Squaretest recognizes 500+ default types from the JDK and various open source libraries, including.- The JDK 8+
- Apache Commons Lang 2 and 3
- Google Guava
- RxJava
- Retrofit
- AWS SDK V1 and V2
- The Spring Framework
Similarly, Squaretest generates doAnswer() statements for dependency interactions that take in Callables or Runnables. These statements invoke the call() or run() methods and return either a CompletableFuture or ListenableFuture when applicable.
Configurable Project-Level and Module-Level Settings
- Configure which Velocity template will be used to create your unit tests in the Project Settings and/or Module Settings.
- Configure where Squaretest will save the generated tests in the Module Settings.
- Squaretest can configure your Module Settings automatically in many cases; see Module Configuration for more.
Add Multiple Test Methods To Your Test Class
Open the test class and select Squaretest | Generate Test Methods (Alt+Insert+Generate Test Methods) to see a list of test methods to add.The list includes tests for the alternate flows described above. For example if a source method calls fooService.getFoo(), and getFoo() can throw an IOException, Squaretest will suggest a test method where fooService.getFoo() is configured to throw an IOException.
The Test Methods Contains Appropriate Boilerplate Code
The generated test method contains:- Local variables for arguments required by the method
- Mockito stubs; i.e. when(), doAnswer() and doThrow() statements
- Code to invoke the method
- An assertEquals() call or groovy assertion statement
- Mockito verify() statements
Add a Test Method to your Test Class
Start typing the name of the test method you want to create to see code completion suggestions based on the methods in your source class. Then select one of the suggested methods to create it.The Test Method Contains Appropriate Boilerplate Code
The generated test method contains:- Local variables for arguments required by the method
- Mockito stubs; i.e. when(), doAnswer() and doThrow() statements
- Code to invoke the method
- An assertEquals() call or groovy assertion statement
- Mockito verify() statements
User Guide
Install
You can install the Squaretest plugin from the IntelliJ plugin repository by following the instructions below.- Go to
- Enter Squaretest in the search bar at the top
- Select the Squaretest plugin, then click the button on the right.
Getting Started
The best way to get started with Squaretest is to use it to create a test by following the instructions below.- Open a file that you want to create unit tests for
- Do one of the following
- Choose from the toolbar
- Type
-
Follow the instructions on the Configure Squaretest Module Settings dialog.
The options are as follows.- Test Language the language to create the tests in (either Java or Groovy)
- Template the Apache Velocity template used to create the tests. The templates are named according to the test runner and mocking framework they use.
- Test Sources Root the directory in which Squaretest will create the tests and any package directories required for this module.
- Promote Test Language and Template to Project Settings whether Squaretest will save the above Test Language and Template in the Project Settings or the Module Settings. The default setting works best for most users.
- Module Configuration whether Squaretest should try to configure the settings for other modules automatically when they are needed or show this dialog every time. The default setting works best for most users. See Module Configuration for more details.
Settings
The Squaretest settings can be changed by doing the following.-
Go to
- Mac OS X Users:
- Click the Squaretest option shown near the bottom of the list on the left.
Application Settings
These settings apply to the Squaretest application. The options are as follows.-
Open the Test File
- In the active editor window
-
In the next editor window if one is available
Squaretest will open the test class in the editor window next to the active editor window if one is available; otherwise, it will open the test class in the active editor window. -
In the next editor window, creating one if needed
Squaretest will open the test class in the editor window next to the active editor window if one is available; otherwise, it will create a new editor window by splitting the active editor window vertically and open the test class in the new window.
-
Manage All Templates
- this shows a dialog enabling you to delete or rename any templates you've created.
-
Manage License
- this shows a dialog enabling you to input or remove your Squaretest license.
-
Data Constructor Limit When Bean Option Available
-
Specifies the longest, nested constructor call (number of parameters) that
will be used to initialize recognized data classes. If the constructor call exceeds this limit
Squaretest will use the zero-argument constructor and bean setter methods to initialize the class,
if one is available.
Recognized Data Classes
Squaretest considers a class to be a data class if it has at least one data annotation. Examples include annotations with canonical names that start with "lombok", "javax.xml.bind.annotation", etc.
-
Specifies the longest, nested constructor call (number of parameters) that
will be used to initialize recognized data classes. If the constructor call exceeds this limit
Squaretest will use the zero-argument constructor and bean setter methods to initialize the class,
if one is available.
-
Constructor Limit When Bean Option Available
- Specifies the longest, nested constructor call (number of parameters) that will be used to initialize classes that contain a zero-argument constructor. If the constructor call exceeds this limit Squaretest will use the zero-argument constructor and bean setter methods to initialize the class. This does not apply to classes with type parameters.
-
Constructor Limit When Other Options Available
- Specifies the longest, nested constructor call (number of parameters) that will be used to initialize classes that contain an alternative initialization method. If the constructor call exceeds this limit Squaretest will use the alternative initialization method to construct the class. This does not apply to classes with type parameters.
-
Final Constructor Limit
- Specifies the longest, nested constructor call (number of parameters) that will be used to initialize classes. If the constructor call exceeds this limit Squaretest will initialize the class to either null or a similar default value.
-
Max Number of Builder Methods to Call
- Specifies the maximum number of builder methods that will be called when initializing a class. Squaretest will recursively invoke builder methods for properties set or accessed in the source class and related classes. This setting limits the number that will be called.
-
Enable Completion Suggestions for Test Methods
- Specifies whether Squaretest should show completion suggestions for test methods when typing in a test class.
Project Settings
The Project Settings apply to an IntelliJ Project. They are as follows.- Test Language the language to create your tests in (either Java or Groovy)
- Template the Apache Velocity template used to create your tests.
- Module Configuration
-
Automatically configure when possible
Squaretest will automatically configure the Module Settings the first time they are needed if the Project Settings contain a template and one of the following is true.- The module contains exactly one test sources root, the test sources root contains source files matching the template language and framework in the Project Settings, and the test sources root's classpath does not contain newer versions of the test framework (e.g. the project framework is JUnit4 and the test sources root has JUnit5 on the classpath). This is the most common scenario.
- The module contains no test sources roots and its dependent modules collectively contains exactly one test sources root that matches the criteria described above.
-
Always ask to configure module settings
Squaretest will always prompt the user to configure settings the first time a test is generated for a module.
-
Automatically configure when possible
Module Settings
The Module Settings apply to a specific module. They are as follows.- Test Language the language to create your tests in (inherited from the Project Settings by default)
- Template the template used to create your tests (inherited from the Project Settings by default)
- Test Sources Root the directory Squaretest will create your tests (and any package directories required) for this module
Keyboard Shortcuts
The Squaretest keyboard shortcuts can be changed by doing the following.- Go to
- Expand the Plugins folder and then the Squaretest folder
- Double-click the Generate Test item and select Add Keyboard Shortcut.
- Set the desired shortcut, then click OK, then OK again.
Create Your Own Template
You can create your own template to use to generate tests by doing the following.- Select a template in either the Project Settings or the Module Settings.
- Make changes to the template code shown in the editor (see the image below)
- Enter a name for your template in the textbox next to the Save Template As button.
- Click Save Template As, then OK
Delete or Rename Templates
You can delete or rename the templates you've created by clicking Manage All Templates in the Application Settings.Template Best Practices
The Velocity templates included with Squaretest are organized into four parts. Most developers will only need to modify the first two parts to update the template to match their code style and conventions. The parts are described below in the order in which they appear in the template code.1. Quick Settings
The first section of the template contains Quick Settings, or variables that configure common code style settings and other aspects of the test class that are applied throughout the template code. See Quick Settings for details about each setting.2. Test Class Rendering Code
This is the code that renders the test class, including the package declaration, import statements and class definition. You can modify this code to match the conventions used in your tests; e.g. add @RunWith annotations, make the test class extend a common base class in your project or module, add comments between the mock variable declarations and the non-mock variable declarations, etc. See Template Data Model for the list of variables available to the test class rendering code.3. Helper Macros
This contains macros used to render parts of the test class; e.g. renderTestMethods($methods). These macros are invoked in the Test Class Rendering Code and can be modified to change how parts of the test class are created.4. InitializeTemplateDataModel Macro
The initializeTemplateDataModel macro configures the data model based on the archetype of the source class and the Quick Settings. This macro is called immediately after the Quick Settings section and sets global variables describing how the test class should be rendered. The global variables are set based on the source class's constructors, fields, methods, annotations and other factors. The variables set by the macro are described here and may be used in the Test Class Rendering Code and the Helper Macros.Power users can modify this macro and its helper macros (defined below the macro) to add or change variables in the data model to accommodate their use cases.
Users should follow the convention of using the initializeTemplateDataModel macro to add or modify variables in the data model, then update the Test Class Rendering Code to check for the new variables and change the output accordingly. This keeps the logic to configure the data model separate from the test class rendering code and allows both to grow in complexity without becoming unmaintainable.
Formatting Tips
Squaretest is designed to allow users to make changes to the template without worrying about formatting. To accomplish this, Squaretest automatically performs several code cleanup tasks on the generated test class, described here. In general, users should follow the guidelines below.- Don't worry about organizing the import statements. These will be organized according to your IDE code style settings in the code cleanup.
-
Use the fully qualified, canonical text when declaring members and variables; e.g. Variable.type.canonicalText.
- These will be shortened automatically in the code cleanup.
- Using fully qualified, canonical text simplifies declaring variables with generic types.
- Don't worry about having extra newlines between sections of the test class. These are removed in the code cleanup.
- Don't worry about over-indenting the Java code or Groovy code in the templates. The test class will be formatted according to your IDE code style settings in the code cleanup.
Advanced Template Editing
Users making significant changes to the templates may wish to use a different editor. The following editors work well.IntelliJ IDEA Ultimate
The IntelliJ IDEA Ultimate IDE includes a good Velocity editor plugin and comes with a free trial. Squaretest also implements the velocity.globalVariableProvider extension point in the Velocity plugin to provide limited code completion suggestions and javadocs for some of the template variables. To use the editor, simply use the Squaretest plugin in IntelliJ IDEA Ultimate. Squaretest will automatically use the editor provided by the Velocity plugin in the Settings menu and Configure Squaretest Module Settings dialog.Other Editors
Squaretest stores the user-created templates in the IntelliJ Template Manager, which stores them in files on the file system. You can edit these files using your editor of choice. Please do not rename them. Also note that you will need to restart IntelliJ IDEA after changing the files. The template files are stored in the following locations.OS | Path |
---|---|
Windows | %APPDATA%\JetBrains\<<IntelliJVersion>>\fileTemplates |
Mac OS X | ~/Library/Application Support/JetBrains/<<IntelliJVersion>>/fileTemplates |
Linux | ~/.config/JetBrains/<<IntelliJVersion>>/fileTemplates |
Template API
The Template API is the data model available to the Velocity template used to create the test class. The Velocity variables that make up the data model are described in the sections below.Quick Settings
The Quick Settings are variables set at the top of the default templates that can be used to set code style and other settings. This section describes the Quick Settings available in the default templates included with Squaretest.Name | Type | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
$dependencyMemberNamePrefix | String | An optional prefix used for test class members that contain dependencies for the source class. If set to "", the template code will use your IDE code style settings instead. | ||||||||
$mockDependencyMemberNamePrefix | String | Similar to $dependencyMemberNamePrefix but only applies to test class members containing mocks. | ||||||||
$parameterLocalFieldNamePrefix | String | An optional prefix for local variables that contain arguments for test methods. If set to "", the template code will use your IDE code style settings instead. | ||||||||
$mockParameterLocalFieldNamePrefix | String | Similar to $parameterLocalFieldNamePrefix but only applies to local variables containing mocks. | ||||||||
$sourceClass.testClassMemberName | String | The name of the member used to store an instance of the source class. The default value is determined by the IDE code style settings. | ||||||||
$sourceClass.testClassLocalFieldName | String | This is similar to $sourceClass.testClassMemberName, but is used when storing an instance of source class in a local field in the test class. | ||||||||
$shouldUseMockitoExtension | boolean | Indicates whether the template should use the JUnit5 Mockito Extension, the JUnit4 Mockito Runner, or the TestNG Mockito Listener. By default, this is set to true if the extension, runner or listener is on the test classpath. | ||||||||
$shouldUseMockitoBdd | boolean | Determines whether the template will use Mockito BDD . | ||||||||
$minNumberOfSettersToCall | int | Sets the minimum number of setters to call when initializing a top-level bean. | ||||||||
$maxNumberOfSettersToCall | int | Sets the maximum number of setters to call when initializing a top-level bean. | ||||||||
$useStaticImportForInitMocks | boolean | This specifies whether MockitoAnnotations.openMocks and related methods should be imported with static imports. | ||||||||
$useMocksForListenerAndCallbackParameters | boolean | If set to true, the template will use mocks for any mockable method parameter whose name ends in "listener" or "callback", ignoring case. | ||||||||
$generateStubsAndVerifyStatements | boolean | If set to true, the template will generate Mockito stubs and verify statements in the test methods. | ||||||||
$initExpressionOverrides | Map<String, String> or Map<String, Map> |
This sets custom initialization expressions for dependencies and method parameters of
certain types. The key is the canonical name of the type. The value is either a String or a Map.
The String value only needs to contain the initialization expression. Maps must contain the following
keys and values.
#set($initExpressionOverrides["android.content.Context"] = { "initExpression" : "RuntimeEnvironment.application", "importsRequired" : ["import org.robolectric.RuntimeEnvironment;"], "shouldStoreInReference" : false }) |
Data Model
Squaretest converts the source class into the following data model available to the Velocity template code.Template Variables
Name | Type | Description |
---|---|---|
$sourceClass | SourceClass | Describes the class for which the test is being generated |
$importsRequired | Set<String> | Imports required by various components in the SourceClass |
$shouldAskToConfirmSettings | boolean | Indicates whether the user invoked the "Generate Test" action or the "Generate Test - Confirm Options" action. |
$isCreatingNewTest | boolean | Indicates whether the template is being invoked to create a new test class or to add test methods to an existing one. |
$springWebMvcTestIncludesSpringExtension | boolean | Indicates whether the Spring @WebMvcTest annotation includes the SpringExtension automatically. |
$ClassUtils | ClassUtils | The ClassUtils class provides methods for obtaining information about classes on test classpath; i.e. accessible from the sources root in which the test class will be created. |
$CodeStyleUtils | CodeStyleUtils | The CodeStyleUtils class provides methods for obtaining recommended names for fields based on the IDE code style settings. |
$FluentList | FluentListFactory | Provides a method for creating an empty FluentList<T>; e.g. $FluentList.of(). |
$ListUtils | ListUtils | The ListUtils class provides methods for operating on lists. |
$MutableBoolean | MutableBooleanFactory | The MutableBooleanFactory class provides methods for creating MutableBooleans. |
$MutableInt | MutableIntFactory | The MutableIntFactory class provides methods for creating MutableInts. |
$MutableObject | MutableObjectFactory | The MutableObjectFactory class provides methods for creating MutableObjects. |
$MutableString | MutableStringFactory | The MutableStringFactory class provides methods for creating MutableObject< String>instances. |
$Newline | String | This contains the newline character. |
$Null | null | This contains null. |
$StringUtils | StringUtils | Contains everything in Apache Commons Lang 3StringUtils, plus a few extra methods. |
$TestInfo | TestInfoFactory | The TestInfoFactory class provides methods for creating TestInfo objects that describe test cases that should be rendered. |
$UiUtils | UiUtils | The UiUtils class provides a method to show a dialog asking the user to confirm settings determined by the template; e.g. confirm which dependencies should be mocked. |
$AltInfo | AltInfoFactory | This class is deprecated. Please use TestInfoFactory. |
Macro Variables
Macro variables are set by the #initializeTemplateDataModel() macro. The #initializeTemplateDataModel() macro is defined at the bottom of the Squaretest templates and is invoked after the Quick Settings section. This macro sets variables used in the test class rendering logic. Those variables are described below.Name | Type | Description |
---|---|---|
$androidActivity |
boolean | This is only set in the Robolectric3 and AndroidJUnit4 templates. This is true if the $sourceClass is an Android Activity. |
$dependencies | FluentList<Variable> | Contains all fields the test class should provide for the instance of $sourceClass |
$hasOpenMocksMethod | boolean | true if MockitoAnnotations.openMocks(..) exists on the test classpath. |
$hasReflectionTestUtils | boolean | boolean indicating whether Spring ReflectionTestUtils is on the test classpath. |
$initMocksMethodName | String | Contains "openMocks" if $hasOpenMocksMethod is true; otherwise, this contains "initMocks". |
$mockMembers | FluentList<Variable> | A subset of $dependencies containing all fields that should be mocked and stored in members in the test class. |
$methodsToTest | FluentList<Method> | A FluentList<Method> containing the methods that should be tested. |
$shouldRenderMockitoCloseable | boolean | boolean indicating whether a mockitoCloseable test class member should be rendered. |
$shouldRenderSetupMethod | boolean | boolean indicating whether a setup method should be rendered. |
$shouldRenderTearDownMethod | boolean | boolean indicating whether a tearDown method should be rendered. |
$shouldRenderSourceClassMember | boolean | boolean indicating whether an instance of the source class should be created and stored in a member of the test class. |
$shouldUseInjectMocks | boolean | a boolean indicating whether @InjectMocks should be used to provide dependencies to the instance of the $sourceClass. |
Macro Variables Used In Source Class Initialization
Name | Type | Description |
---|---|---|
$fieldsThatCannotBeSet |
boolean | Source class members that Squaretest does not know how to set. |
$fieldsToSetWithReflection |
boolean | Source class members that should be set via reflection to initialize the source class. |
$packageLocalFieldsToSet |
boolean | The package local fields that should be set to initialize the source class. |
$packageLocalFieldsWithInlineMocks |
boolean | subset of $packageLocalFieldsToSet that contains package local fields that are set to inline mocks. |
$setterMethodsToCall |
boolean | The setter methods that should be used to initialize the source class. |
$shouldCreateSourceClassInEachTestMethod |
boolean | boolean indicating whether the source class should be constructed in each test method as opposed to the setup(..) method. |
$sourceClassConstructor |
boolean | The constructor that should be used to construct the source class. |
Macro Variables in Spring Templates
The #initializeTemplateDataModel() macro sets the following additional variables in Spring templates.Name | Type | Description |
---|---|---|
$allModelAttributeProviderMethods |
FluentList<Method> | The list of all model attribute provider methods in the source class and its super classes. |
$basePath |
String | The base uri path for the spring controller under test, or "" if one is not set. |
$controllerMethods |
FluentList<Method> | The list of controller methods in the source class. |
$hasClassSecurityAnnotations |
boolean | This is true if the $sourceClass has Spring security annotations. |
$mockMvcMemberName |
String | A String containing the name to use for the MockMvc member field. |
$modelAttributeProviderMethodDIs |
FluentList<DI> | The list of dependency interactions in all of the model attribute provider methods in the source class. |
$modelAttributeProviderMethods |
FluentList<Method> | The list of model attribute provider methods in the source class. |
$restController |
boolean | This is true if the $sourceClass is a Spring rest controller. |
$shouldRenderMockMvc |
boolean | boolean indicating whether a Spring MockMvc test class member should be rendered. |
$shouldUseSpringExtension |
boolean | boolean indicating whether the JUnit 5 SpringExtension should be used. |
$shouldUseSpringWebMvcTest |
boolean | boolean indicating whether the @WebMvcTest annotation should be used. |
$springController |
boolean | This is true if the $sourceClass is a Spring controller. |
Macro Variables Set Based on Mockito BDD Setting
The #initializeTemplateDataModel() macro sets the following variables based on the $shouldUseMockitoBdd Quick Setting.Name | Type | Description |
---|---|---|
$doAnswer |
String | Contains either 'doAnswer' or 'willAnswer' |
$doReturn |
String | Contains either 'doReturn' or 'willReturn' |
$doThrow |
String | Contains either 'doThrow' or 'willThrow' |
$thenReturn |
String | Contains either 'thenReturn' or 'willReturn' |
$thenThrow |
String | Contains either 'thenThrow' or 'willThrow' |
$when |
String | Contains either 'when' or 'given' |
Template Variable Types
SourceClass | ||
---|---|---|
Property Name | Type | Description |
abstract | boolean | True if source class is abstract. |
abstractClassBody | String | Contains the body of an anonymous instance of the abstract class that contains stubs for all of the abstract methods. |
allSuperClasses | FluentList<SourceClass> | Contains all super classes and interfaces of this source class. |
allSuperTypeNames | FluentList<String> | Contains the canonical names of all super classes and interfaces of this class. |
annotations | FluentList<Annotation> | Contains the annotations on the source class. |
constructors | FluentList<Constructor> | Contains all constructors in the class, including the default constructor provided by the java language spec if applicable. |
constructorsAnnotatedWith( String... annotationNames) |
FluentList<Constructor> | Returns all constructors annotated with at least one of the provided annotations. The list: annotationNames can include simple and canonical names. Any value containing a dot (.) will be treated as a canonical name. |
dtoBean | boolean | True if source class is a data transfer object (DTO) bean. |
dtoBeanWithInputIoProperty | boolean | True if the source class is a data transfer object (DTO) bean that contains an Input I/O property; e.g. S3Object in the AWS SDK V1 API. |
enum | boolean | True if source class is an enum. |
enumFirstValue | String | Contains the first value in the enum if source class is an enum; otherwise, returns null. |
enumValues | FluentList<String> | Returns the values in the enum if source class is an enum; otherwise, returns the empty list. |
fields | FluentList<ClassMember> | Contains all fields (static and instance) in the source class |
fieldsAnnotatedWith( String... annotationNames) |
FluentList<ClassMember> | Returns all fields annotated with at least one of the provided annotations. The list: annotationNames can include simple and canonical names. Any value containing a dot (.) will be treated as a canonical name. |
hasAnnotation( List<String> annotationNames) |
boolean | Returns whether this class is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotation( String... annotationNames) |
boolean | Returns whether this class is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotationWithPrefix( List<String> prefixes) |
boolean | Returns whether this class has an annotation that starts with one of the provided prefixes. |
hasAnnotationWithPrefix( String... prefixes) |
boolean | Returns whether this class has an annotation that starts with one of the provided prefixes. |
hasGenerics | boolean | True if source class has one or more type parameters. |
instanceFields | FluentList<ClassMember> | Contains all instance fields in source class. |
instanceMethods | FluentList<Method> | All instance methods in the source class. |
is(String canonicalName) |
boolean | Returns true if this class is an instance of the provided canonical name. |
isAll(List<String> canonicalNames) |
boolean | Returns true if this class is an instance of all of the provided canonical names. |
isAll(String... canonicalNames) |
boolean | Returns true if this class is an instance of all of the provided canonical names. |
isAny(List<String> canonicalNames) |
boolean | Returns true if this class is an instance of one of the provided canonical names. |
isAny(String... canonicalNames) |
boolean | Returns true if this class is an instance of one of the provided canonical names. |
methods | FluentList<Method> | All methods in the source class |
methodsAnnotatedWith( String... annotationNames) |
FluentList<Method> | Returns all methods annotated with at least one of the provided annotations. The list: annotationNames can include simple and canonical names. Any value containing a dot (.) will be treated as a canonical name. |
name | String | Contains the name of the source class. |
packageLocalConstructors | FluentList<Constructor> | All package-local constructors in source class. |
packageLocalInstanceFields | FluentList<ClassMember> | Contains all package-local instance fields in source class. |
packageLocalInstanceMethods | FluentList<Method> | All package-local instance methods in the source class |
packageLocalStaticFields | FluentList<ClassMember> | Contains all package-local static fields in source class. |
packageLocalStaticMethods | FluentList<Method> | All package local static methods in the source class |
packageName | String | Contains the package name from the package declaration statement in source class. |
packageVisibleStaticCreatorMethods | FluentList<Method> | Contains all static methods that return an instance of source class and have package-local access or higher. |
preferredConstructor | Constructor | Mutable field that, by default, contains longest constructor (constructor with the most arguments) with at least package-local access or higher (Public, Protected or Package Local). |
preferredInitSetters | FluentList<Method> | Contains the list of preferred setters to use to initialize the source class. For most cases, this will be the list of simpleSetters. |
privateConstructors | FluentList<Constructor> | All private constructors in source class |
privateInstanceFields | FluentList<ClassMember> | Contains all private instance fields in source class. |
privateInstanceMethods | FluentList<Method> | All private instance methods in the source class |
privateStaticFields | FluentList<ClassMember> | Contains all private static fields in source class. |
privateStaticMethods | FluentList<Method> | All private static methods in the source class |
protectedConstructors | FluentList<Constructor> | All protected constructors in source class. |
protectedInstanceFields | FluentList<ClassMember> | Contains all protected instance fields in source class. |
protectedInstanceMethods | FluentList<Method> | All protected instance methods in the source class |
protectedStaticFields | FluentList<ClassMember> | Contains all protected static fields in source class. |
protectedStaticMethods | FluentList<Method> | All protected static methods in the source class |
publicConstructors | FluentList<Constructor> | All public constructors in the source class, including the default constructor provided by the java language spec if applicable. |
publicInstanceFields | FluentList<ClassMember> | Contains all public instance fields in source class. |
publicInstanceMethods | FluentList<Method> | All public instance methods in the source class |
publicStaticFields | FluentList<ClassMember> | Contains all public static fields in source class. |
publicStaticMethods | FluentList<Method> | All public static methods in the source class |
sealed | boolean | True if source class is sealed. |
simpleGetters | FluentList<Method> | Simple getter methods in the source class. |
simpleSetters | FluentList<Method> | Simple setter methods in the source class. |
singleton | boolean | True if source class is a singleton; false otherwise. |
singletonAccessExpression | String | The expression needed to access the instance of the singleton if source class is a singleton; e.g. getInstance(), instance(), INSTANCE; null otherwise. |
staticFields | FluentList<ClassMember> | Contains all static fields in source class. |
staticMethods | FluentList<Method> | All static methods in the source class |
testClassLocalFieldName | String | Mutable field containing the name of the local field used to store an instance of the source class. The default value is determined by the IDE code style settings. |
testClassMemberName | String | Mutable field containing the name of the member used to store an instance of the source class. The default value is determined by the IDE code style settings. |
type | Type | Contains the type of the source class. |
Method | ||
---|---|---|
Property Name | Type | Description |
abstract | boolean | True if the method is abstract. |
accessLevel | String | Returns a String representing the access level for this method. Possible values are private, protected, packagePrivate, public. |
annotations | FluentList<Annotation> | Contains the annotations on the method. |
constructor | boolean | True if the method is a constructor. |
containingClass | SourceClass | Returns the class that contains this method. For Api.DependencyInteraction methods, this returns null. |
declaredExceptions | FluentList<Exception> | The list of exceptions the method declares to be thrown. |
dependencyInteractions | FluentList<DI> | All dependency interactions (field, method) pairs this method interacts with in the source class. This includes dependency interactions in this method's body as well as interactions in other methods in the same source class that are called from this method's body. |
deprecated | boolean | True if the method is deprecated. |
getter | boolean | True if the method is a getter. |
getterOrSetter | boolean | True if the method is a getter or a setter. |
getSuperMethodParametersAtIndex( int index) |
FluentList<Variable> | Returns all super method parameters at the specified index. |
hasAnnotation( List<String> annotationNames) |
boolean | Returns whether this method is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotation( String... annotationNames) |
boolean | Returns whether this method is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotationWithPrefix( List<String> prefixes) |
boolean | Returns whether this method has an annotation that starts with one of the provided prefixes. |
hasAnnotationWithPrefix( String... prefixes) |
boolean | Returns whether this method has an annotation that starts with one of the provided prefixes. |
inferredNullable | boolean | True if Squaretest has inferred this method can return null. |
inMainSourceClass | boolean | True if the method is in the main Source Class (the class the test is being created for). |
javadocExceptions | FluentList<Exception> | The list of exceptions declared in the method's Javadoc tags. This may include exceptions declared in the super methods' Javadoc tags. |
jaxbListGetter | boolean | True if the method is likely a getter method generate by JAXB that returns a list. Such getter methods do not have corresponding setters. Developers modify the list by adding items to the returned list. |
name | String | The name of the method |
native | boolean | True if the method is native. |
overloadSuffix | String | The suffix to append to the test method name to avoid method-name conflicts in the test class. |
packageLocal | boolean | True if the method is package-local; false otherwise. |
parameters | FluentList<Variable> | The method’s parameters |
private | boolean | True if the method is private; false otherwise. |
protected | boolean | True if the method is protected; false otherwise. |
public | boolean | True if the method is public; false otherwise. |
returnType | Type | The return type of the method or null if the method has none. |
returnTypeCanBeAbsent | boolean | True if Squaretest has inferred this method can return either null or an "absent" value; e.g. Optional.empty(). |
setter | boolean | True if this method is a setter. |
shouldTest | boolean | Mutable property indicating whether this method should be tested. |
shouldUseSimpleTest | boolean | Whether the template should render a simple, 1-line test method for this source method. |
simpleGetter | boolean | This is deprecated. Please Use the getter property. |
simpleGetterOrSetter | boolean | This is deprecated. Please use the getterOrSetter property. |
simpleSetter | boolean | This is deprecated. Please use the setter property. |
static | boolean | True if the method is static. |
superMethods | FluentList<Method> | Contains all super methods this method overrides. |
targetField | ClassMember | Returns the target field this method is a getter or setter for, or null if this is not a getter or setter or if the target field could not be determined. |
throwsCheckedException | boolean | True if the method throws a checked exception. |
throwsException | boolean | True if the method throws an exception. |
DependencyInteraction | ||
---|---|---|
Property Name | Type | Description |
field | ClassMember | The ClassMember on which this DependencyInteraction's method is called. |
method | Method | The Method called on the field in this DependencyInteraction. |
methodCallExpression | MethodCallExpression | Contains information about the method call; e.g. the actual types of the arguments passed to the method if they can be determined. |
MethodCallExpression | ||
---|---|---|
Property Name | Type | Description |
arguments | FluentList<ArgumentExpression> | The arguments used in the method call. |
type | Type | The type the method call expression evaluates to or null if the method has no return type. This type contains actual types for any type parameters inferred by the method call or class on which the method was called. |
ArgumentExpression | ||
---|---|---|
Property Name | Type | Description |
actualType | Type | The actual type of the argument. For arguments of type: T or Class<T>, Squaretest will attempt to provide the actual type used in the method call. |
declaredType | Type | The declared type of the argument. This is the same as the type in the corresponding Method. |
Constructor |
---|
Constructor is the same as Method, but implements Comparable<Constructor> such that it is ordered by number of parameters. |
Variable | ||
---|---|---|
Property Name | Type | Description |
annotations | FluentList<Annotation> | Contains the annotations on the Variable. |
containingMethod | Method | The method that contains this parameter or null if this is a ClassMember. |
declaredName | String | The declared name for the variable; for ClassMembers this property contains the name of the member this it was created from; for method parameters, this contains the name of the parameter. |
declaredNameWithoutPrefix | String | The declaredName with any prefixes removed; for method parameters, this is just the declaredName; for ClassMembers, this is the name with any recognized leading prefix (_, __, m, my, our) removed. |
defaultInitExpression | String | Alias for type.defaultInitExpression. |
final | boolean | True if the variable is declared to be final. |
hasAnnotation( List<String> annotationNames) |
boolean | Returns whether this Variable is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotation( String... annotationNames) |
boolean | Returns whether this Variable is annotated with one of the provided annotation names. Annotation names can include simple and canonical names. |
hasAnnotationWithPrefix( List<String> prefixes) |
boolean | Returns whether this Variable has an annotation that starts with one of the provided prefixes. |
hasAnnotationWithPrefix( String... prefixes) |
boolean | Returns whether this Variable has an annotation that starts with one of the provided prefixes. |
initExpression | String | Alias for type.initExpression. |
member | boolean | True if this Variable is a ClassMember. |
shouldBeMocked | boolean | Alias for type.shouldBeMocked. |
shouldStoreInReference | boolean | Set to true by default; this may be modified by logic in the template code based on the Quick Settings. |
testClassLocalFieldName | String | For method parameters, this is the same as the declared name. For ClassMembers, this is determined based on the declared name and the IDE code style settings; this may be modified by logic in the template code based on the Quick Settings. |
testClassMemberName | String | For ClassMembers, this is the same as the declaredName; for method parameters, this is determined based on the declared name and the IDE code style settings; this may be modified by logic in the template code based on the Quick Settings. |
type | Type | The Type of the variable. |
ClassMember | ||
---|---|---|
Name | Type | Description |
Everything in Variable | N/A | N/A |
accessLevel | String | Returns a String representing the access level for this member. Possible values are private, protected, packagePrivate, public. |
final | boolean | True if the member is final. |
getters | FluentList<Method> | Getter methods for this ClassMember |
packageLocal | boolean | True if the member field is package-local |
possibleSourceVariables | FluentList<Variable> | List of references to Variables that could have provided the value for this ClassMember. This list includes pointers to constructor parameter(s) this field is assigned to. The ClassMember itself is also included in the list. |
private | boolean | True if the member field is private |
protected | boolean | True if the member field is protected |
public | boolean | True if the member field is public |
setters | FluentList<Method> | Setter methods for this ClassMember |
static | boolean | True if the member is static. |
transient | boolean | True if the member is declared to be transient. |
visibleToTestClass | boolean | True if the member is visible to the test class. |
Exception | ||
---|---|---|
Name | Type | Description |
checked | boolean | True if this is a checked exception. |
type | Type | The type for this exception. |
Type | ||
---|---|---|
Name | Type | Description |
absentInitExpression | String | Represents an absent value for this type; e.g. Optional.empty(). This is usually "null". |
allNames | FluentList<String> | Contains this type's canonical name as well as the canonical names of all super types of the type. |
allNestedTypeParamsOverrideEquals | boolean | All type parameters override Object.equals() or are Class<T>, and all type parameters have allNestedTypeParamsOverrideEquals set to true. |
allSuperTypeNames | FluentList<String> | Contains the canonical names of all super types of the type. |
array | boolean | True if the type is an array; false otherwise. |
brokenIoInitExpression | String | Represents a broken I/O value for this type; e.g. new BrokenInputStream(), or null if there isn't one. |
canonicalName | String | Contains the canonical name of the type or null if the type has no canonical name, or the canonical name could not be determined. |
canonicalNameOrName | String | Contains the canonical name if it is non-null. Otherwise, this contains the name of the type. |
canonicalText | String | Contains the canonical text of the type. |
classT | boolean | True if the type is Class<T>; false otherwise. |
closeable | boolean | True if the type implements AutoCloseable. |
createInitExpressionWith LocalFieldBeans( List<Type> types) |
String | Computes and returns an initExpression that uses the testClassLocalFieldNames of the provided types instead of their initExpressions. |
deepArrayComponentType | Type | Contains the innermost component type for the array, if this type is an array. Otherwise, this contains null. |
defaultInitExpression | String | The default expression used to obtain an instance of the class or “null” for types that are not Common Types. |
dtoBean | boolean | True if the type is a DTO Bean. |
dtoBeanWithInputIoProperty | boolean | True if the type is a data transfer object (DTO) bean that contains an Input I/O property; e.g. S3Object in the AWS SDK V1 API. |
emptyInitExpression | String | Represents an empty value for this type; e.g. Collections.emptyList(), or null if there isn't one. |
emptyIoInitExpression | String | Represents an empty I/O value for this type; e.g. InputStream.nullInputStream(), or null if there isn't one. |
enum | boolean | True if the type is an enum. |
failureInitExpression | String | Represents a failure value for this type; e.g. CompletableFuture.failedFuture(new Exception("message")), or null if there isn't one. |
generic | boolean | True if the type is generic. |
initExpression | String | Mutable field set to defaultInitExpression by default. This may be modified by the template code; see the Quick Settings initExpressionOverrides for details. |
initExpressionBeans | FluentList<Type> | List of DTO beans used in the defaultInitExpression. |
is(String canonicalName) |
boolean | Returns true if this type is an instance of the provided canonical name. |
isAll(List<String> canonicalNames) |
boolean | Returns true if this type is an instance of all of the provided canonical names. |
isAll(String... canonicalNames) |
boolean | Returns true if this type is an instance of all of the provided canonical names. |
isAny(List<String> canonicalNames) |
boolean | Returns true if this type is an instance of one of the provided canonical names. |
isAny(String... canonicalNames) |
boolean | Returns true if this type is an instance of one of the provided canonical names. |
isOrHasAnyNestedTypeParamWith( List<String> canonicalNames) |
boolean | Returns true if this type is an instance of one of the provided canonical names or has a type parameter that is an instance of one of the provided canonical names. |
isOrHasAnyNestedTypeParamWith( String... canonicalNames) |
boolean | Returns true if this type is an instance of one of the provided canonical names or has a type parameter that is an instance of one of the provided canonical names. |
mockable | boolean | True if the type is mockable (non-final, non-static and not an enum) |
nested | boolean | True if the type is nested inside a class. |
optional | boolean | True if the type is optional. |
overridesEquals | boolean | True if the type overrides Object.equals(...); false otherwise. |
packageLocal | boolean | True if the type is package-local; false otherwise. |
parameters | FluentList<Type> | Contains the list of type parameters for this type. |
primitive | boolean | True if the type is primitive; false otherwise. |
private | boolean | True if the type is private; false otherwise. |
protected | boolean | True if the type is protected; false otherwise. |
public | boolean | True if the type is public; false otherwise. |
shouldBeMocked | boolean | Mutable field set to false for types with defaultInitExpressions != "null"; In all other cases, this is set to mockable; this may be modified by logic in the template code based on the Quick Settings. |
shouldBeSpied | boolean | Mutable field indicating whether this type should be spied; i.e. Mockito.spy(..). |
shouldStoreInReference | boolean | A boolean indicating whether the value of the initExpression should be stored in a reference (local variable or test class member) or used inline when needed. |
simple | boolean | True if the type is simple. A simple type is one whose value should be used inline rather than stored in a local variable. Examples are: primitive types, enums, certain immutable types from the java.time package, etc. |
springSimple | boolean | True if Spring components consider this type to be a simple value type; see BeanUtils.isSimpleValueType(Class<?>). |
static | boolean | True if the type is a static class. |
testClassLocalFieldName | String | Mutable property containing the name to use when storing an instance of this type in a local variable. |
testClassMemberName | String | Mutable property containing the name to use when storing an instance of this type in a test class member. |
type | Type | A convenience property that returns this type. |
wildcard | boolean | True if the type is a wildcard; e.g. "? extends Foo". |
TestInfo | ||
---|---|---|
Name | Type | Description |
method | Method | The source method this test case should cover. |
expectedValueAbsent | boolean | True if the source method is expected to return an absent value; e.g. Optional.empty(). |
expectedValueNull | boolean | True if the source method is expected to return null. |
expectedValueTrue | boolean | True if the source method is expected to return true. |
expectedException | Exception | The exception the source method is expected to throw. |
mockedDIs | FluentList<DI> | The mocked dependency interactions used in this test case. |
paramWithEmptyIo | Variable | Mutable property containing the source method parameter that should contain an empty I/O value in this test case. |
paramWithBrokenIo | Variable | Mutable property containing the source method parameter that should contain a broken I/O value in this test case. |
subjectDi | DependencyInteraction | The dependency interaction that is the subject of this test. |
subjectDiReturnsEmpty | boolean | True if the subject DependencyInteraction should return an empty value. |
subjectDiReturnsAbsent | boolean | True if the subject DependencyInteraction should return an absent value. |
subjectDiReturnsEmptyIo | boolean | True if the subject DependencyInteraction should return an empty I/O Value. |
subjectDiReturnsBrokenIo | boolean | True if the subject DependencyInteraction should return a broken I/O Value. |
subjectDiReturnsFailure | boolean | True if the subject DependencyInteraction should return a failure value. |
subjectDiExceptionToThrow | Exception | The exception the subject DependencyInteraction should throw in this test case. |
shouldReturnAbsent( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should return an absent value. |
shouldReturnEmpty( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should return an empty value. |
shouldReturnEmptyIo( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should return an empty I/O value. |
shouldReturnBrokenIo( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should return a broken I/O value. |
shouldThrowException( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should throw an exception in this test case. |
getExceptionToThrow( DependencyInteraction di) |
Exception | Returns the Exception the provided DependencyInteraction should throw in this test case. |
shouldReturnFailure( DependencyInteraction di) |
boolean | Returns true if the provided DependencyInteraction should return a failure value in this test case. |
Annotation | ||
---|---|---|
Name | Type | Description |
canonicalName | String | Contains the canonical name of the annotation or null if the canonical name could not be determined. |
canonicalNameOrName | String | Contains the canonical name if it is non-null. Otherwise, this contains the name of the annotation. |
name | String | Contains the name of the annotation. |
parameters | FluentList<AnnotationParameter> | Contains the list of parameters passed to this annotation. |
AnnotationParameter | ||
---|---|---|
Name | Type | Description |
key | String | Contains the key of this annotation (key, value) pair. |
value | AnnotationValue | Contains the value of this annotation (key, value) pair. |
AnnotationValue | ||
---|---|---|
Name | Type | Description |
text | String | Contains the text of the annotation value. |
FluentList<T> | ||
---|---|---|
Method | Return Type | Description |
Everything in List<T> | N/A | N/A |
first | T | Returns the first item in the list or null if the list is empty. |
second | T | Returns the second item in the list or null if the list contains fewer than two items. |
third | T | Returns the third item in the list or null if the list contains fewer than three items. |
fourth | T | Returns the fourth item in the list or null if the list contains fewer than four items. |
fifth | T | Returns the fifth item in the list or null if the list contains fewer than five items. |
last | T | Returns the last item in the list or null if the list is empty. |
concat( Collection<T> listToAppend) |
FluentList<T> | Returns a new list containing the items from this list followed by the items from listToAppend. |
containsAny( List<?> searchItems) |
boolean | Returns whether this list contains any of the provided searchItems. |
containsAnyWith( String attrNameExp, Object... searchValues) |
boolean | Returns whether the list contains an item with property: attrNameExp and a value in the searchValues. |
containsAnyWithAnnotation( List<String> annotations) |
boolean | Returns whether the list contains any items with at least one of the provided annotations. |
containsAnyWithAnnotation( String... annotations) |
boolean | Returns whether the list contains any items with at least one of the provided annotations. |
containsAnyWithAnnotationPrefix( List<String> annotations) |
boolean | Returns whether the list contains any items with at least one annotation that starts with one of the given prefixes. |
containsAnyWithAnnotationPrefix( String... prefixes) |
boolean | Returns whether the list contains any items with at least one annotation that starts with one of the given prefixes. |
containsAnyWithNonNull( String attrNameExp) |
boolean | Returns whether the list contains an item with property: attrNameExp and a value that is not null. |
containsAnyWithPrefix( String attrNameExp, List<String>) |
boolean | Returns whether the list contains an item with property: attrNameExp and a value that starts with one of the provided prefixes. |
containsAnyWithPrefix( String attrNameExp, String... prefixes) |
boolean | Returns whether the list contains an item with property: attrNameExp and a value that starts with one of the provided prefixes. |
containsAnyWithRegex( String attrNameExp, String regex) |
boolean | Returns whether the list contains an item with property: attrNameExp and a value that matches regular expression. |
filter( String attrNameExp, Object... searchValues) |
FluentList<T> | Returns the list of items with property: attrNameExp and a value in searchValues. |
filter( String attrNameExp) |
FluentList<T> | Returns the list of items with property: attrNameExp and value: true. This is equivalent to "filter(attrNameExp, true)". |
filter2( String attrNameExp, List<?> searchValues) |
FluentList<T> | This returns a new list containing items in the list that have a property with name: attrNameExp and a value in searchValues. |
filterItemsWithAnnotation( List<String> annotations) |
FluentList<T> | Returns a list containing all items with at least one of the provided annotations. The annotations parameter may contain simple names or canonical names. |
filterItemsWithAnnotation( String... annotations) |
FluentList<T> | Returns a list containing all items with at least one of the provided annotations. The annotations parameter may contain simple names or canonical names. |
filterItemsWithAnnotationPrefix( List<String> annotations) |
FluentList<T> | Returns a list containing all items with at least one annotation that starts with one of the given prefixes. |
filterItemsWithAnnotationPrefix( String... prefixes) |
FluentList<T> | Returns a list containing all items with at least one annotation that starts with one of the given prefixes. |
filterItemsWithAny( String attrNameExp, List<Object> attrValues) |
FluentList<T> | This returns a new list containing items in the list that have a property with name: attrNameExp and a value in attrValues. |
filterItemsWithPrefix( String attrNameExp, List<String> prefixes) |
FluentList<T> | Returns the list of items with property: attrNameExp and a value that starts with one of the provided prefixes. |
filterItemsWithPrefix( String attrNameExp, String... prefixes) |
FluentList<T> | Returns the list of items with property: attrNameExp and a value that starts with one of the provided prefixes. |
filterItemsWithRegex( String attrNameExp, String regex) |
FluentList<T> | Returns the list of items with property: attrNameExp and a value that matches the provided regular expression. |
filterItemsWithSameSourceVar( DependencyInteraction di) |
FluentList<DI> | Returns a FluentList containing DependencyInteractions whose field.possibleSourceVariables contain no elements in common with the provided dependencyInteraction.field.possibleSourceVariables. |
filterOut( String attrNameExp, Object... searchValues) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value in searchValues. |
filterOut( String attrNameExp) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value of true. |
filterOut(String attrNameExp) | FluentList<T> | Returns a list excluding items with property: attrNameExp and a value of true. This is equivalent to "filterOut(attrNameExp, true)" |
filterOut2( String attrNameExp, List<?> searchValues) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value in searchValues. |
filterOutItem( T itemToRemove) |
FluentList<T> | Returns a list excluding all items equal to itemToRemove. |
filterOutItemsWithAnnotation( List<String> annotations) |
FluentList<T> | Returns a list containing all items that do not have at least one of the provided annotations. The annotations parameter may contain simple names or canonical names. |
filterOutItemsWithAnnotation( String... annotations) |
FluentList<T> | Returns a list containing all items that do not have at least one of the provided annotations. The annotations parameter may contain simple names or canonical names. |
filterOutItemsWithAnnotationPrefix( List<String> annotations) |
FluentList<T> | Returns a list containing all items that do not have at least one annotation that starts with one of the given prefixes. |
filterOutItemsWithAnnotationPrefix( String... prefixes) |
FluentList<T> | Returns a list containing all items that do not have at least one annotation that starts with one of the given prefixes. |
filterOutItemsWithPrefix( String attrNameExp, List<String> prefixes) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value that starts with one of the provided prefixes. |
filterOutItemsWithPrefix( String attrNameExp, String... prefixes) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value that starts with one of the provided prefixes. |
filterOutItemsWithRegex( String attrNameExp, String regex) |
FluentList<T> | Returns a list excluding items with property: attrNameExp and a value that matches the provided regular expression. |
filterOutItemsWithSameSourceVar( DependencyInteraction di) |
FluentList<DI> | Returns a FluentList containing DependencyInteractions whose field.possibleSourceVariables contain at least one element in common with the provided dependencyInteraction.field.possibleSourceVariables. |
flatMap(String attrNameExp) |
FluentList<?> | Invokes the given attrNameExp on each item in the list and returns a new list containing all values returned from the invocations. If an invocation returns a List, all items in the list are added to the return list; i.e. the lists are flattened. |
getOrNull( int index) |
T | Returns the item in the list at the specified index or null if the index is out of bounds for the list. |
indexOfAny( String attrNameExp, Object... searchValues) |
int | Returns the index of the first item in the list contains property: attrNameExp and a value in searchValues; this returns -1 if no such item is in the list. |
intersection( Iterable iter) |
FluentList<T> | Returns the intersection of this list and the provided Iterable. |
itemsAfter(obj) | FluentList<T> | Returns a list containing items after obj or an empty list of obj is not present in the list. |
itemsBefore(obj) | FluentList<T> | Returns a list containing items before obj or an empty list of obj is not present in the list. |
join(delimiter) | String | Returns a String containing each element of this list joined with the provided delimiter. |
limit(num) | FluentList<T> | Returns a new FluentList with the first num elements of this list. |
map(String attrNameExp) |
FluentList<?> | Returns a list containing the results of invoking the given attributeNameExpression on each element of this list. |
satisfiedBy( List<? extends Api.Variable> dependencies) |
FluentList<DI> | Returns the list of dependency interactions satisfied by the provided dependencies. More formally, a DependencyInteraction di is included in the list if di.field.possibleSourceVariables.intersection(dependencies) is not empty. |
union( Iterable iter, String attrNameExp) |
FluentList<T> | Returns the union of this list and the provided Iterable using the attribute value retrieved by attrNameExp to determine equality. |
union( Iterable iter) |
FluentList<T> | Returns the union of this list and the provided Iterable. |
CodeStyleUtils | ||
---|---|---|
Method | Return Type | Description |
beginMethodScope() |
void |
Informs CodeStyleUtils this is the start of a Java or Groovy method. Invoking this method enables CodeStyleUtils to suggest local variable names that do not conflict others declared in the same method. |
endMethodScope() |
void |
Informs CodeStyleUtils this is the end of a Java or Groovy method. Invoking this method enables CodeStyleUtils to suggest local variable names that do not conflict others declared in the same method. |
suggestLocalFieldName( String className) |
String |
Returns the suggested name to use for a local field of type className based on the IDE code style settings. |
suggestMemberName( String className) |
String |
Returns the suggested name to use for a member of type className based on the IDE code style settings. |
updateLocalFieldNameWithMethodScope( Type type) |
void |
Updates the testClassLocalFieldName property of the provided type in a way that avoids name collisions with other variables or types that were updated after CodeStyleUtils.beginMethodScope() was invoked. |
updateLocalFieldNameWithMethodScope( Variable variable) |
void |
Updates the testClassLocalFieldName property of the provided variable in a way that avoids name collisions with other variables or types that were updated after CodeStyleUtils.beginMethodScope() was invoked. |
updateMemberFieldNameWithClassScope( Variable variable) |
void |
Updates the testClassMemberName property of the provided variable in a way that avoids name collisions with other variables or types passed to this method during test generation. |
ClassUtils | ||
---|---|---|
Method | Return Type | Description |
hasBeanWithUsedProperty( Type type) |
boolean |
Returns whether this type has a bean with at least one used property in its Type.initExpressionBeans list. |
isInTestClasspath( String canonicalName) |
boolean |
Returns whether a class with the given canonical name is in the classpath of the sources root in which the test class will be created. |
removePackageQualifiers( String canonicalText) |
boolean |
Attempts to remove the package qualifiers from the provided canonical text and returns the result. |
resolveClass( Type type) |
SourceClass | Returns a SourceClass object for the provided type or null if one could not be found. Note: the Method.dependencyInteraction properties will not be populated in the returned SourceClass. |
resolveClass( Variable var) |
SourceClass | Returns a SourceClass object for the provided Variable or null if one could not be found. Note: the Method.dependencyInteraction properties will not be populated in the returned SourceClass. |
resolveClass( String canonicalName) |
SourceClass | Returns a SourceClass object for the provided canonical name or null if one could not be found. Note: the Method.dependencyInteraction properties will not be populated in the returned SourceClass. |
UiUtils | ||
---|---|---|
Method | Return Type | Description |
askUserToConfirmSettings( Map<String, Object> settings) |
Map<String, Object> | Shows a dialog asking the user to confirm the provided settings. |
askUserToConfirmSettingsV2( Map<String, Object> settings) |
Map<String, Object> | Shows a dialog asking the user to confirm the provided settings. |
FluentList | ||
---|---|---|
Method | Return Type | Description |
emptyList() |
FluentList<T> | Returns an empty FluentList<T>. |
of(T... items) |
FluentList<T> | Returns a mutable FluentList<T> containing the provided items. |
MutableBoolean | ||
---|---|---|
Method | Return Type | Description |
create(boolean value) |
MutableBoolean | Returns a MutableBoolean with the specified value. |
MutableInt | ||
---|---|---|
Method | Return Type | Description |
create(int value) |
MutableInt | Returns a MutableInt with the specified value. |
MutableObject | ||
---|---|---|
Method | Return Type | Description |
create() |
MutableObject | Returns a MutableObject with the value set to null. |
create(Object value) |
MutableObject | Returns a MutableObject with the specified value. |
MutableString | ||
---|---|---|
Method | Return Type | Description |
create() |
MutableString | Returns a MutableObject<String> with the value set to null. |
create(String value) |
MutableString | Returns a MutableObject<String> with the specified value. |
TestInfoFactory | ||
---|---|---|
Method | Return Type | Description |
fromDiThatThrows( sourceMethod, mockedDIs, di, diExceptionToThrow) |
TestInfo | Returns an TestInfo object with the provided source method, mocked dependency interactions, dependency interaction that should throw an exception and the exception that should be thrown. |
fromDiToReturnAbsent( sourceMethod, mockedDIs, di) |
TestInfo | Returns an TestInfo object with the provided sourceMethod, mocked dependency interactions and the dependency interaction that should return null or an absent value for the test case. |
fromDiToReturnBrokenIo( sourceMethod, mockedDIs, di) |
TestInfo | Returns an TestInfo object with the provided sourceMethod, mocked dependency interactions and the dependency interaction that should return a broken I/O value for the test case. |
fromDiToReturnEmpty( sourceMethod, mockedDIs, di) |
TestInfo | Returns an TestInfo object with the provided sourceMethod, mocked dependency interactions and the dependency interaction that should return an empty value for the test case. |
fromDiToReturnEmptyIo( sourceMethod, mockedDIs, di) |
TestInfo | Returns an TestInfo object with the provided sourceMethod, mocked dependency interactions and the dependency interaction that should return an empty I/O value for the test case. |
fromDiToReturnFailure( sourceMethod, mockedDIs, di) |
TestInfo | Returns an TestInfo object with the provided sourceMethod, mocked dependency interactions and the dependency interaction that should return a failure value for the test case. |
fromExpectedException( sourceMethod, mockedDIs, expectedException) |
TestInfo | Returns a TestInfo object with the provided source method, mocked dependency interactions and expectedException. |
fromParamWithBrokenIo( sourceMethod, mockedDIs, param) |
TestInfo | Returns a TestInfo object with the provided sourceMethod, mocked dependency interactions and parameter that should contain a broken I/O value for the test case. |
fromParamWithEmptyIo( sourceMethod, mockedDIs, param) |
TestInfo | Returns a TestInfo object with the provided sourceMethod, mocked dependency interactions and parameter that should contain an empty I/O value for the test case. |
newValue() |
TestInfo | Returns an empty TestInfo object. |
primaryFlow( sourceMethod, mockedDIs) |
TestInfo | Returns a TestInfo representing the primary flow test case for the provided source method and mocked dependency interactions. |
updateDependencies( FluentList<Variable> dependencies) |
TestInfo | Updates the dependencies used to create test cases. |
ListUtils | ||
---|---|---|
Method | Return Type | Description |
nullToEmpty(List<?> theList) |
FluentList<?> |
Returns theList if it is non-null and an empty FluentList otherwise. |
StringUtils | ||
---|---|---|
Method | Return Type | Description |
Everything in StringUtils | N/A | Everything in org.apache.commons.lang3.StringUtils. |
longest( String... strings) |
String | Returns the longest String provided. |
longest( List<String> strings) |
String | Returns the longest String provided. |
shortest( String... strings) |
String | Returns the shortest String provided. |
shortest( List<String> strings) |
String | Returns the shortest String provided. |
substringsBetween( String str, String tag) |
String[] | Searches a String for substrings delimited by the provided tag, and returns all matching substrings in an array. |
Method Comment Hints
Previous version of Squaretest included Velocity templates with special comments of the form: "#* sq_hint:setup_comment *#". These are no longer used.
Newlines
Squaretest removes all but one trailing newline at the end of the generated unit test file. This allows developers to have space between macros and comments without concern that they will appear in the unit tests.
Squaretest also replaces each group of 3 or more newlines in the generated unit test file with 2 newlines. This removes the need for developers to add extra branching logic to templates to ensure the unit test contains an appropriate number of newlines between sections.
Code Cleanup
Squaretest performs several, automated code cleanup tasks on the generated test class. These include the following.
- Optimize imports according to the IDE code style settings.
-
Shorten class references (replace fully qualified names with imports)
- This enables developers to use fully qualified names throughout the template without having them appear in the generated test class.
-
Reformat all code in the test class according to the IDE code style settings.
- This enables developers to indent the template code in a way that is easy to read without having to worry about the generated Java code being over-indented.
-
Remove unnecessary semicolons.
- This allows the Groovy templates to use semicolons to mark the ends of statements.
-
Remove unnecessary throws clauses.
- This enables developers to include "throws Exception" on all generated methods instead of needing to determine whether the clause is necessary in each method.
Examples
The following examples show source classes along with their corresponding test classes that were generated by Squaretest. In many cases, the user only needs to fill in the placeholder values, and update the assertions to complete the tests.Standard Component
The source class is a standard Java component that retrieves deals from a web service, converts them into display versions and returns them. The test class generated by Squaretest contains tests for the following cases.- The primary flow where the deals service returns a list containing one item.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
package com.squaretest.demo1;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class DealsServiceAdapter {
private static final Logger Log = Logger.getLogger(DealsServiceAdapter.class.getName());
private final DealsServiceClient dealsService;
private final MetricsAdapter metricsAdapter;
public DealsServiceAdapter(
final DealsServiceClient dealsService,
final MetricsAdapter metricsAdapter) {
this.dealsService = dealsService;
this.metricsAdapter = metricsAdapter;
}
public List<DisplayDeal> safeGetDeals(final String userId) {
try {
final GetDealsRequest request = new GetDealsRequest();
request.setUserId(userId);
return convertToDisplayDeals(dealsService.getDeals(request).getActiveDeals());
} catch (final ServiceException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordServiceException(userId, e);
return Collections.emptyList();
} catch (final NetworkException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordNetworkException(userId, e);
return Collections.emptyList();
}
}
private List<DisplayDeal> convertToDisplayDeals(final List<Deal> deals) {
return deals.stream().map(deal -> new DisplayDeal(deal.getId(), deal.getProductName(),
deal.getPrice(), deal.getImageUrl())).collect(Collectors.toList());
}
}
package com.squaretest.demo1;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class DealsServiceAdapterTest {
@Mock
private DealsServiceClient mockDealsService;
@Mock
private MetricsAdapter mockMetricsAdapter;
private DealsServiceAdapter dealsServiceAdapterUnderTest;
@BeforeEach
void setUp() {
dealsServiceAdapterUnderTest = new DealsServiceAdapter(mockDealsService, mockMetricsAdapter);
}
@Test
void testSafeGetDeals() throws Exception {
// Setup
final List<DisplayDeal> expectedResult = List.of(
new DisplayDeal("id", "productName", new BigDecimal("0.00"), "imageUri"));
// Configure DealsServiceClient.getDeals(...).
final DealsServiceResponse dealsServiceResponse = new DealsServiceResponse();
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setImageUrl("imageUri");
dealsServiceResponse.setActiveDeals(List.of(deal));
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenReturn(dealsServiceResponse);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(expectedResult, result);
}
@Test
void testSafeGetDeals_DealsServiceClientThrowsServiceException() throws Exception {
// Setup
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(ServiceException.class);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(Collections.emptyList(), result);
verify(mockMetricsAdapter).recordServiceException(eq("userId"), any(ServiceException.class));
}
@Test
void testSafeGetDeals_DealsServiceClientThrowsNetworkException() throws Exception {
// Setup
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(NetworkException.class);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(Collections.emptyList(), result);
verify(mockMetricsAdapter).recordNetworkException(eq("userId"), any(NetworkException.class));
}
}
Standard Component with JAXB
The source class is the same as the Standard Component but with a DealsServiceResponse class generated by JAXB. Deals are added to the response by invoking response.getActiveDeals().add(..). The generated test class contains tests for the following cases.- The primary flow where the deals service returns a list containing one item.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
package com.squaretest.demo20;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class DealsServiceAdapter {
private static final Logger Log = Logger.getLogger(DealsServiceAdapter.class.getName());
private final DealsServiceClient dealsService;
private final MetricsAdapter metricsAdapter;
public DealsServiceAdapter(
final DealsServiceClient dealsService,
final MetricsAdapter metricsAdapter) {
this.dealsService = dealsService;
this.metricsAdapter = metricsAdapter;
}
public List<DisplayDeal> safeGetDeals(final String userId) {
try {
final GetDealsRequest request = new GetDealsRequest();
request.setUserId(userId);
return convertToDisplayDeals(dealsService.getDeals(request).getActiveDeals());
} catch (final ServiceException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordServiceException(userId, e);
return Collections.emptyList();
} catch (final NetworkException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordNetworkException(userId, e);
return Collections.emptyList();
}
}
private List<DisplayDeal> convertToDisplayDeals(final List<Deal> deals) {
return deals.stream().map(deal -> new DisplayDeal(deal.getId(), deal.getProductName(),
deal.getPrice(), deal.getImageUrl())).collect(Collectors.toList());
}
}
package com.squaretest.demo20;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class DealsServiceAdapterTest {
@Mock
private DealsServiceClient mockDealsService;
@Mock
private MetricsAdapter mockMetricsAdapter;
private DealsServiceAdapter dealsServiceAdapterUnderTest;
@BeforeEach
void setUp() {
dealsServiceAdapterUnderTest = new DealsServiceAdapter(mockDealsService, mockMetricsAdapter);
}
@Test
void testSafeGetDeals() throws Exception {
// Setup
final List<DisplayDeal> expectedResult = List.of(
new DisplayDeal("id", "productName", new BigDecimal("0.00"), "imageUri"));
// Configure DealsServiceClient.getDeals(...).
final DealsServiceResponse dealsServiceResponse = new DealsServiceResponse();
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setImageUrl("imageUri");
dealsServiceResponse.getActiveDeals().addAll(List.of(deal));
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenReturn(dealsServiceResponse);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(expectedResult, result);
}
@Test
void testSafeGetDeals_DealsServiceClientThrowsServiceException() throws Exception {
// Setup
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(ServiceException.class);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(Collections.emptyList(), result);
verify(mockMetricsAdapter).recordServiceException(eq("userId"), any(ServiceException.class));
}
@Test
void testSafeGetDeals_DealsServiceClientThrowsNetworkException() throws Exception {
// Setup
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(NetworkException.class);
// Run the test
final List<DisplayDeal> result = dealsServiceAdapterUnderTest.safeGetDeals("userId");
// Verify the results
assertEquals(Collections.emptyList(), result);
verify(mockMetricsAdapter).recordNetworkException(eq("userId"), any(NetworkException.class));
}
}
Asynchronous Component
The source class is an asynchronous Java component that performs the same task as the Standard Component but in a background thread. The class returns a CompletableFuture that callers can use to manage the background task. The test class contains tests for the following cases.- The primary flow where the deals service returns a list containing one item.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
package com.squaretest.demo8;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class DealsServiceAdapterAsync {
private static final Logger Log = Logger.getLogger(DealsServiceAdapterAsync.class.getName());
private final DealsServiceClient dealsService;
private final ExecutorService executorService;
private final MetricsAdapter metricsAdapter;
public DealsServiceAdapterAsync(
final DealsServiceClient dealsService,
final ExecutorService executorService,
final MetricsAdapter metricsAdapter) {
this.dealsService = dealsService;
this.executorService = executorService;
this.metricsAdapter = metricsAdapter;
}
public CompletableFuture<List<DisplayDeal>> getDeals(final String userId) {
return CompletableFuture.supplyAsync(() -> {
try {
return getDealsInternal(userId);
} catch (final ServiceException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordServiceException(userId, e);
throw new CompletionException(e);
} catch (final NetworkException e) {
Log.log(Level.WARNING, "Exception querying deals service.", e);
metricsAdapter.recordNetworkException(userId, e);
throw new CompletionException(e);
}
}, executorService);
}
private List<DisplayDeal> getDealsInternal(final String userId) throws ServiceException, NetworkException {
final GetDealsRequest request = new GetDealsRequest();
request.setUserId(userId);
return convertToDisplayDeals(dealsService.getDeals(request).getActiveDeals());
}
private List<DisplayDeal> convertToDisplayDeals(final List<Deal> deals) {
return deals.stream().map(deal -> new DisplayDeal(deal.getId(), deal.getProductName(),
deal.getPrice(), deal.getImageUrl())).collect(Collectors.toList());
}
}
package com.squaretest.demo8;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class DealsServiceAdapterAsyncTest {
@Mock
private DealsServiceClient mockDealsService;
@Mock
private ExecutorService mockExecutorService;
@Mock
private MetricsAdapter mockMetricsAdapter;
private DealsServiceAdapterAsync dealsServiceAdapterAsyncUnderTest;
@BeforeEach
void setUp() {
dealsServiceAdapterAsyncUnderTest = new DealsServiceAdapterAsync(mockDealsService, mockExecutorService,
mockMetricsAdapter);
}
@Test
void testGetDeals() throws Exception {
// Setup
doAnswer(invocation -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
}).when(mockExecutorService).execute(any(Runnable.class));
// Configure DealsServiceClient.getDeals(...).
final DealsServiceResponse dealsServiceResponse = new DealsServiceResponse();
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setImageUrl("imageUri");
dealsServiceResponse.setActiveDeals(List.of(deal));
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenReturn(dealsServiceResponse);
// Run the test
final CompletableFuture<List<DisplayDeal>> result = dealsServiceAdapterAsyncUnderTest.getDeals("userId");
// Verify the results
verify(mockExecutorService).execute(any(Runnable.class));
}
@Test
void testGetDeals_DealsServiceClientThrowsServiceException() throws Exception {
// Setup
doAnswer(invocation -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
}).when(mockExecutorService).execute(any(Runnable.class));
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(ServiceException.class);
// Run the test
final CompletableFuture<List<DisplayDeal>> result = dealsServiceAdapterAsyncUnderTest.getDeals("userId");
// Verify the results
verify(mockExecutorService).execute(any(Runnable.class));
verify(mockMetricsAdapter).recordServiceException(eq("userId"), any(ServiceException.class));
}
@Test
void testGetDeals_DealsServiceClientThrowsNetworkException() throws Exception {
// Setup
doAnswer(invocation -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
}).when(mockExecutorService).execute(any(Runnable.class));
when(mockDealsService.getDeals(any(GetDealsRequest.class))).thenThrow(NetworkException.class);
// Run the test
final CompletableFuture<List<DisplayDeal>> result = dealsServiceAdapterAsyncUnderTest.getDeals("userId");
// Verify the results
verify(mockExecutorService).execute(any(Runnable.class));
verify(mockMetricsAdapter).recordNetworkException(eq("userId"), any(NetworkException.class));
}
}
AWS SDK V1 S3 Adapter
The source class is a component that retrieves purchase order PDF documents from an S3 bucket. The test class generated by Squaretest contains tests for the following cases.- The primary flow where the bucket contains the purchase order.
- The alternate flow where the bucket contains a purchase order with no content (an empty object).
- The alternate flow where the bucket contains a purchase order, but the connection is interrupted while it is being downloaded.
- The alternate flow where the bucket does not contain the purchase order or S3 returns an error.
- The alternate flow where S3 could not be reached due to a network error on the client side.
package com.squaretest.demo3;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.S3Object;
import org.apache.commons.lang3.Validate;
import org.apache.pdfbox.pdmodel.PDDocument;
import java.io.IOException;
public class PurchaseOrderStore {
private static final String PathFormat = "%s/purchaseOrder.pdf";
private final AmazonS3 s3Client;
private final MetricAdapter metricAdapter;
private final String bucketName;
public PurchaseOrderStore(
final AmazonS3 s3Client,
final MetricAdapter metricAdapter,
final String bucketName) {
this.s3Client = s3Client;
this.metricAdapter = metricAdapter;
this.bucketName = bucketName;
}
public PDDocument getPurchaseOrder(final String orderId) throws PurchaseOrderStoreException {
Validate.notBlank(orderId, "orderId cannot be blank");
final String path = String.format(PathFormat, orderId);
try (final S3Object s3Object = s3Client.getObject(bucketName, path)) {
final PDDocument purchaseOrderDoc = PDDocument.load(s3Object.getObjectContent());
metricAdapter.recordPurchaseOrderDocumentDownloaded(orderId);
return purchaseOrderDoc;
} catch (final AmazonServiceException e) {
metricAdapter.recordServiceException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("AmazonServiceException while downloading object with path: %s", path), e);
} catch (final SdkClientException e) {
metricAdapter.recordClientException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("SdkClientException while downloading object with path: %s", path), e);
} catch (final IOException e) {
metricAdapter.recordIOException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("IOException while downloading object with path: %s", path), e);
}
}
}
package com.squaretest.demo3;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.S3Object;
import org.apache.commons.io.input.BrokenInputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class PurchaseOrderStoreTest {
@Mock
private AmazonS3 mockS3Client;
@Mock
private MetricAdapter mockMetricAdapter;
private PurchaseOrderStore purchaseOrderStoreUnderTest;
@BeforeEach
void setUp() {
purchaseOrderStoreUnderTest = new PurchaseOrderStore(mockS3Client, mockMetricAdapter, "bucketName");
}
@Test
void testGetPurchaseOrder() throws Exception {
// Setup
// Configure AmazonS3.getObject(...).
final S3Object spyS3Object = spy(new S3Object());
spyS3Object.setBucketName("bucketName");
spyS3Object.setKey("key");
spyS3Object.setObjectContent(new ByteArrayInputStream("content".getBytes()));
when(mockS3Client.getObject("bucketName", "key")).thenReturn(spyS3Object);
// Run the test
final PDDocument result = purchaseOrderStoreUnderTest.getPurchaseOrder("orderId");
// Verify the results
verify(spyS3Object).close();
verify(mockMetricAdapter).recordPurchaseOrderDocumentDownloaded("orderId");
}
@Test
void testGetPurchaseOrder_AmazonS3ReturnsNoContent() throws Exception {
// Setup
// Configure AmazonS3.getObject(...).
final S3Object spyS3Object = spy(new S3Object());
spyS3Object.setBucketName("bucketName");
spyS3Object.setKey("key");
spyS3Object.setObjectContent(InputStream.nullInputStream());
when(mockS3Client.getObject("bucketName", "key")).thenReturn(spyS3Object);
// Run the test
final PDDocument result = purchaseOrderStoreUnderTest.getPurchaseOrder("orderId");
// Verify the results
verify(spyS3Object).close();
verify(mockMetricAdapter).recordPurchaseOrderDocumentDownloaded("orderId");
}
@Test
void testGetPurchaseOrder_AmazonS3ReturnsBrokenIo() throws Exception {
// Setup
// Configure AmazonS3.getObject(...).
final S3Object spyS3Object = spy(new S3Object());
spyS3Object.setBucketName("bucketName");
spyS3Object.setKey("key");
spyS3Object.setObjectContent(new BrokenInputStream());
when(mockS3Client.getObject("bucketName", "key")).thenReturn(spyS3Object);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(spyS3Object).close();
verify(mockMetricAdapter).recordIOException(eq("orderId"), any(IOException.class));
}
@Test
void testGetPurchaseOrder_AmazonS3ThrowsSdkClientException() {
// Setup
when(mockS3Client.getObject("bucketName", "key")).thenThrow(SdkClientException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordClientException(eq("orderId"), any(SdkClientException.class));
}
@Test
void testGetPurchaseOrder_AmazonS3ThrowsAmazonServiceException() {
// Setup
when(mockS3Client.getObject("bucketName", "key")).thenThrow(AmazonServiceException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordServiceException(eq("orderId"), any(AmazonServiceException.class));
}
}
AWS SDK V2 S3 Adapter
The source class is a component that retrieves purchase order PDF documents from an S3 bucket. The test class generated by Squaretest contains tests for the following cases.- The primary flow where the bucket contains the purchase order.
- The alternate flow where the bucket contains a purchase order with no content (an empty object).
- The alternate flow where the bucket contains a purchase order, but the connection is interrupted while it is being downloaded.
- The alternate flow where the bucket does not contain the purchase order.
- The alternate flow where S3 could not be reached due to a network error on the client side.
- The alternate flow where S3 returns a service error.
package com.squaretest.demo2;
import org.apache.commons.lang3.Validate;
import org.apache.pdfbox.pdmodel.PDDocument;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import software.amazon.awssdk.services.s3.model.S3Exception;
import java.io.IOException;
public class PurchaseOrderStore {
private static final String PathFormat = "%s/purchaseOrder.pdf";
private final S3Client s3Client;
private final MetricAdapter metricAdapter;
private final String bucketName;
public PurchaseOrderStore(
final S3Client s3Client,
final MetricAdapter metricAdapter,
final String bucketName) {
this.s3Client = s3Client;
this.metricAdapter = metricAdapter;
this.bucketName = bucketName;
}
public PDDocument getPurchaseOrder(final String orderId) throws PurchaseOrderStoreException {
Validate.notBlank(orderId, "orderId cannot be blank");
final String path = String.format(PathFormat, orderId);
try (final ResponseInputStream<GetObjectResponse> s3Object = s3Client.getObject(
GetObjectRequest.builder().bucket(bucketName).key(path).build())) {
final PDDocument purchaseOrderDoc = PDDocument.load(s3Object);
metricAdapter.recordPurchaseOrderDocumentDownloaded(orderId);
return purchaseOrderDoc;
} catch (final NoSuchKeyException e) {
metricAdapter.recordPurchaseOrderNotFound(orderId, e);
throw new PurchaseOrderStoreException(String.format("S3Object with path: %s not found", path), e);
} catch (final S3Exception e) {
metricAdapter.recordServiceException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("S3Exception while downloading object with path: %s", path), e);
} catch (final SdkClientException e) {
metricAdapter.recordClientException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("SdkClientException while downloading object with path: %s", path), e);
} catch (final IOException e) {
metricAdapter.recordIOException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("IOException while downloading object with path: %s", path), e);
}
}
}
package com.squaretest.demo2;
import org.apache.commons.io.input.BrokenInputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.http.AbortableInputStream;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class PurchaseOrderStoreTest {
@Mock
private S3Client mockS3Client;
@Mock
private MetricAdapter mockMetricAdapter;
private PurchaseOrderStore purchaseOrderStoreUnderTest;
@BeforeEach
void setUp() {
purchaseOrderStoreUnderTest = new PurchaseOrderStore(mockS3Client, mockMetricAdapter, "bucketName");
}
@Test
void testGetPurchaseOrder() throws Exception {
// Setup
// Configure S3Client.getObject(...).
final ResponseInputStream<GetObjectResponse> spyResponseInputStream = spy(
new ResponseInputStream<>(GetObjectResponse.builder().build(),
AbortableInputStream.create(new ByteArrayInputStream("objectContent".getBytes()))));
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenReturn(spyResponseInputStream);
// Run the test
final PDDocument result = purchaseOrderStoreUnderTest.getPurchaseOrder("orderId");
// Verify the results
verify(spyResponseInputStream).close();
verify(mockMetricAdapter).recordPurchaseOrderDocumentDownloaded("orderId");
}
@Test
void testGetPurchaseOrder_S3ClientReturnsNoContent() throws Exception {
// Setup
// Configure S3Client.getObject(...).
final ResponseInputStream<GetObjectResponse> spyResponseInputStream = spy(
new ResponseInputStream<>(GetObjectResponse.builder().build(),
AbortableInputStream.create(InputStream.nullInputStream())));
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenReturn(spyResponseInputStream);
// Run the test
final PDDocument result = purchaseOrderStoreUnderTest.getPurchaseOrder("orderId");
// Verify the results
verify(spyResponseInputStream).close();
verify(mockMetricAdapter).recordPurchaseOrderDocumentDownloaded("orderId");
}
@Test
void testGetPurchaseOrder_S3ClientReturnsBrokenIo() throws Exception {
// Setup
// Configure S3Client.getObject(...).
final ResponseInputStream<GetObjectResponse> spyResponseInputStream = spy(
new ResponseInputStream<>(GetObjectResponse.builder().build(),
AbortableInputStream.create(new BrokenInputStream())));
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenReturn(spyResponseInputStream);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(spyResponseInputStream).close();
verify(mockMetricAdapter).recordIOException(eq("orderId"), any(IOException.class));
}
@Test
void testGetPurchaseOrder_S3ClientThrowsNoSuchKeyException() {
// Setup
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenThrow(NoSuchKeyException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordPurchaseOrderNotFound(eq("orderId"), any(NoSuchKeyException.class));
}
@Test
void testGetPurchaseOrder_S3ClientThrowsInvalidObjectStateException() {
// Setup
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenThrow(InvalidObjectStateException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordServiceException(eq("orderId"), any(S3Exception.class));
}
@Test
void testGetPurchaseOrder_S3ClientThrowsAwsServiceException() {
// Setup
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenThrow(AwsServiceException.class);
// Run the test
assertThrows(AwsServiceException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
}
@Test
void testGetPurchaseOrder_S3ClientThrowsSdkClientException() {
// Setup
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenThrow(SdkClientException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordClientException(eq("orderId"), any(SdkClientException.class));
}
@Test
void testGetPurchaseOrder_S3ClientThrowsS3Exception() {
// Setup
when(mockS3Client.getObject(GetObjectRequest.builder()
.bucket("bucketName")
.key("key")
.build())).thenThrow(S3Exception.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordServiceException(eq("orderId"), any(S3Exception.class));
}
}
AWS SDK V1 DynamoDBMapper
The source class is a component that retrieves orders from a DynamoDB table. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the table contains the order.
- The alternate flow where the table does not contain the order.
- The alternate flow where the order could not be retrieved due to a network error or service error.
package com.squaretest.demo11;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import org.apache.commons.lang3.Validate;
public class OrderStore {
private final DynamoDBMapper dynamoDBMapper;
private final MetricsAdapter metricsAdapter;
public OrderStore(
final DynamoDBMapper dynamoDBMapper,
final MetricsAdapter metricsAdapter) {
this.dynamoDBMapper = dynamoDBMapper;
this.metricsAdapter = metricsAdapter;
}
public Order getOrder(final String orderId) throws OrderStoreException {
Validate.notBlank(orderId, "orderId cannot be blank");
// Make the service call.
final Order order;
try {
order = dynamoDBMapper.load(Order.class, orderId);
} catch (final Exception e) {
metricsAdapter.recordOrderStoreException(orderId, e);
throw new OrderStoreException(e);
}
// Validate the order.
if (order == null) {
metricsAdapter.recordOrderNotFound(orderId);
throw new OrderNotFoundException(orderId);
}
metricsAdapter.recordOrderFound(orderId);
return order;
}
}
package com.squaretest.demo11;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class OrderStoreTest {
@Mock
private DynamoDBMapper mockDynamoDBMapper;
@Mock
private MetricsAdapter mockMetricsAdapter;
private OrderStore orderStoreUnderTest;
@BeforeEach
void setUp() {
orderStoreUnderTest = new OrderStore(mockDynamoDBMapper, mockMetricsAdapter);
}
@Test
void testGetOrder() throws Exception {
// Setup
// Configure DynamoDBMapper.load(...).
final Order order = new Order();
order.setId("id");
order.setShipAddress("shipAddress");
order.setShipDate(LocalDateTime.of(2020, 1, 1, 0, 0, 0, 0).toInstant(ZoneOffset.UTC));
final Product product = new Product();
product.setId("id");
order.setProducts(List.of(product));
when(mockDynamoDBMapper.load(Order.class, "orderId")).thenReturn(order);
// Run the test
final Order result = orderStoreUnderTest.getOrder("orderId");
// Verify the results
verify(mockMetricsAdapter).recordOrderFound("orderId");
}
@Test
void testGetOrder_DynamoDBMapperReturnsNull() {
// Setup
when(mockDynamoDBMapper.load(Order.class, "orderId")).thenReturn(null);
// Run the test
assertThrows(OrderNotFoundException.class, () -> orderStoreUnderTest.getOrder("orderId"));
verify(mockMetricsAdapter).recordOrderNotFound("orderId");
}
@Test
void testGetOrder_DynamoDBMapperThrowsAmazonDynamoDBException() {
// Setup
when(mockDynamoDBMapper.load(Order.class, "orderId")).thenThrow(AmazonDynamoDBException.class);
// Run the test
assertThrows(OrderStoreException.class, () -> orderStoreUnderTest.getOrder("orderId"));
verify(mockMetricsAdapter).recordOrderStoreException(eq("orderId"), any(Exception.class));
}
}
AWS SDK V2 DynamoDBMapper
The source class is a component that retrieves orders from a DynamoDB table. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the table contains the order.
- The alternate flow where the table does not contain the order.
- The alternate flow where the order could not be retrieved due to a network error.
- The alternate flow where the order could not be retrieved due to a service error.
package com.squaretest.demo12;
import org.apache.commons.lang3.Validate;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
public class OrderStore {
private final DynamoDbTable<Order> ordersTable;
private final MetricsAdapter metricsAdapter;
public OrderStore(
final DynamoDbTable<Order> ordersTable,
final MetricsAdapter metricsAdapter) {
this.ordersTable = ordersTable;
this.metricsAdapter = metricsAdapter;
}
public Order getOrder(final String orderId) throws OrderStoreException {
Validate.notBlank(orderId, "orderId cannot be blank");
// Make the service call.
final Order order;
try {
order = ordersTable.getItem(Key.builder().partitionValue(orderId).build());
} catch (final Exception e) {
metricsAdapter.recordOrderStoreException(e);
throw new OrderStoreException(e);
}
// Validate the order.
if (order == null) {
metricsAdapter.recordOrderNotFound(orderId);
throw new OrderStoreException("Order with ID " + orderId + " not found.");
}
metricsAdapter.recordOrderRetrieved(orderId);
return order;
}
}
package com.squaretest.demo12;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class OrderStoreTest {
@Mock
private DynamoDbTable<Order> mockOrdersTable;
@Mock
private MetricsAdapter mockMetricsAdapter;
private OrderStore orderStoreUnderTest;
@BeforeEach
void setUp() {
orderStoreUnderTest = new OrderStore(mockOrdersTable, mockMetricsAdapter);
}
@Test
void testGetOrder() throws Exception {
// Setup
// Configure DynamoDbTable.getItem(...).
final Order order = new Order();
order.setId("id");
order.setShipAddress("shipAddress");
order.setShipDate(LocalDateTime.of(2020, 1, 1, 0, 0, 0, 0).toInstant(ZoneOffset.UTC));
final Product product = new Product();
product.setId("id");
order.setProducts(List.of(product));
when(mockOrdersTable.getItem(Key.builder()
.partitionValue("orderId")
.build())).thenReturn(order);
// Run the test
final Order result = orderStoreUnderTest.getOrder("orderId");
// Verify the results
verify(mockMetricsAdapter).recordOrderRetrieved("orderId");
}
@Test
void testGetOrder_DynamoDbTableReturnsNull() {
// Setup
when(mockOrdersTable.getItem(Key.builder()
.partitionValue("orderId")
.build())).thenReturn(null);
// Run the test
assertThrows(OrderStoreException.class, () -> orderStoreUnderTest.getOrder("orderId"));
verify(mockMetricsAdapter).recordOrderNotFound("orderId");
}
@Test
void testGetOrder_DynamoDbTableThrowsSdkClientException() {
// Setup
when(mockOrdersTable.getItem(Key.builder()
.partitionValue("orderId")
.build())).thenThrow(SdkClientException.class);
// Run the test
assertThrows(OrderStoreException.class, () -> orderStoreUnderTest.getOrder("orderId"));
verify(mockMetricsAdapter).recordOrderStoreException(any(Exception.class));
}
@Test
void testGetOrder_DynamoDbTableThrowsDynamoDbException() {
// Setup
when(mockOrdersTable.getItem(Key.builder()
.partitionValue("orderId")
.build())).thenThrow(DynamoDbException.class);
// Run the test
assertThrows(OrderStoreException.class, () -> orderStoreUnderTest.getOrder("orderId"));
verify(mockMetricsAdapter).recordOrderStoreException(any(Exception.class));
}
}
AWS SDK V2 Comprehend
The source class is a component that uses Amazon Comprehend to retrieve the list of entities mentioned in the provided text. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the service returns a response with one entity.
- The alternate flow where the service returns a response indicating the request was invalid.
- The alternate flow where the service returns a response indicating the resource specified in the request was not available.
- The alternate flow where the text specified in the request was too large.
- The alternate flow where an internal service error occurred while processing the request.
- The alternate flow where the connection was interrupted while making the request.
package com.squaretest.demo18;
import org.apache.commons.lang3.StringUtils;
import software.amazon.awssdk.services.comprehend.ComprehendClient;
import software.amazon.awssdk.services.comprehend.model.DetectEntitiesRequest;
import software.amazon.awssdk.services.comprehend.model.DetectEntitiesResponse;
import software.amazon.awssdk.services.comprehend.model.Entity;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class LanguageAnalyzer {
private final ComprehendClient comService;
public LanguageAnalyzer(final ComprehendClient comService) {
this.comService = comService;
}
public List<String> getEntitiesMentioned(final String text) throws LanguageServiceException {
if (StringUtils.isBlank(text)) {
return Collections.emptyList();
}
// Make the service call.
final DetectEntitiesRequest detectEntitiesRequest = DetectEntitiesRequest.builder()
.text(text)
.languageCode("en")
.build();
final DetectEntitiesResponse detectEntitiesResult;
try {
detectEntitiesResult = comService.detectEntities(detectEntitiesRequest);
} catch (final Exception e) {
throw new LanguageServiceException("Exception querying Amazon Comprehend service.", e);
}
// Return the entities mentioned.
return detectEntitiesResult.entities().stream().map(Entity::text).collect(Collectors.toList());
}
}
package com.squaretest.demo18;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.comprehend.ComprehendClient;
import software.amazon.awssdk.services.comprehend.model.*;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class LanguageAnalyzerTest {
@Mock
private ComprehendClient mockComService;
private LanguageAnalyzer languageAnalyzerUnderTest;
@BeforeEach
void setUp() {
languageAnalyzerUnderTest = new LanguageAnalyzer(mockComService);
}
@Test
void testGetEntitiesMentioned() throws Exception {
// Setup
// Configure ComprehendClient.detectEntities(...).
final DetectEntitiesResponse detectEntitiesResponse = DetectEntitiesResponse.builder()
.entities(Entity.builder()
.text("text")
.build())
.build();
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenReturn(detectEntitiesResponse);
// Run the test
final List<String> result = languageAnalyzerUnderTest.getEntitiesMentioned("text");
// Verify the results
assertEquals(List.of("value"), result);
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsInvalidRequestException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(InvalidRequestException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsResourceUnavailableException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(ResourceUnavailableException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsTextSizeLimitExceededException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(TextSizeLimitExceededException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsUnsupportedLanguageException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(UnsupportedLanguageException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsInternalServerException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(InternalServerException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsAwsServiceException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(AwsServiceException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsSdkClientException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(SdkClientException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
@Test
void testGetEntitiesMentioned_ComprehendClientThrowsComprehendException() {
// Setup
when(mockComService.detectEntities(DetectEntitiesRequest.builder()
.text("text")
.languageCode(LanguageCode.EN)
.build())).thenThrow(ComprehendException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
}
Google Cloud Storage
The source class is a component that retrieves purchase orders from a Google Cloud Storage bucket. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the bucket contains the purchase order.
- The alternate flow where an error occurs while downloading the purchase order.
package com.squaretest.demo16;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import org.apache.commons.lang3.Validate;
import org.apache.pdfbox.pdmodel.PDDocument;
import java.io.IOException;
public class PurchaseOrderStore {
private static final String PathFormat = "%s/purchaseOrder.pdf";
private final Storage storage;
private final MetricAdapter metricAdapter;
private final String bucketName;
public PurchaseOrderStore(
final Storage storage,
final MetricAdapter metricAdapter,
final String bucketName) {
this.storage = storage;
this.metricAdapter = metricAdapter;
this.bucketName = bucketName;
}
public PDDocument getPurchaseOrder(final String orderId) throws PurchaseOrderStoreException {
Validate.notBlank(orderId, "orderId cannot be blank");
final String path = String.format(PathFormat, orderId);
try {
final byte[] content = storage.readAllBytes(bucketName, path);
final PDDocument purchaseOrderDoc = PDDocument.load(content);
metricAdapter.recordPurchaseOrderRetrieved(orderId);
return purchaseOrderDoc;
} catch (final StorageException e) {
metricAdapter.recordStorageException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("StorageException while downloading object with path: %s", path), e);
} catch (final IOException e) {
metricAdapter.recordIOException(orderId, e);
throw new PurchaseOrderStoreException(
String.format("IOException while parsing object with path: %s", path), e);
}
}
}
package com.squaretest.demo16;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PurchaseOrderStoreTest {
@Mock
private Storage mockStorage;
@Mock
private MetricAdapter mockMetricAdapter;
private PurchaseOrderStore purchaseOrderStoreUnderTest;
@BeforeEach
void setUp() {
purchaseOrderStoreUnderTest = new PurchaseOrderStore(mockStorage, mockMetricAdapter, "bucketName");
}
@Test
void testGetPurchaseOrder() throws Exception {
// Setup
when(mockStorage.readAllBytes("bucketName", "blob")).thenReturn("content".getBytes());
// Run the test
final PDDocument result = purchaseOrderStoreUnderTest.getPurchaseOrder("orderId");
// Verify the results
verify(mockMetricAdapter).recordPurchaseOrderRetrieved("orderId");
}
@Test
void testGetPurchaseOrder_StorageThrowsStorageException() {
// Setup
when(mockStorage.readAllBytes("bucketName", "blob")).thenThrow(StorageException.class);
// Run the test
assertThrows(PurchaseOrderStoreException.class, () -> purchaseOrderStoreUnderTest.getPurchaseOrder("orderId"));
verify(mockMetricAdapter).recordStorageException("orderId",
new StorageException(0, "message", "reason", new Exception("message")));
}
}
Google Cloud Natural Language
The source class is a component that uses Google Cloud Natural Language to retrieve the list of entities mentioned in the provided text. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the service returns a response with one entity.
- The alternate flow where the service returns an error.
package com.squaretest.demo17;
import com.google.cloud.language.v1.*;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class LanguageAnalyzer {
private final LanguageServiceClient languageService;
public LanguageAnalyzer(final LanguageServiceClient languageService) {
this.languageService = languageService;
}
public List<String> getEntitiesMentioned(final String text) throws LanguageServiceException {
if (StringUtils.isBlank(text)) {
return Collections.emptyList();
}
// Make the service call.
final AnalyzeEntitiesResponse response;
try {
final Document doc = Document.newBuilder().setContent(text).setType(Document.Type.PLAIN_TEXT).build();
final AnalyzeEntitiesRequest request =
AnalyzeEntitiesRequest.newBuilder()
.setDocument(doc)
.setEncodingType(EncodingType.UTF16)
.build();
response = languageService.analyzeEntities(request);
} catch (final Exception e) {
throw new LanguageServiceException("Exception querying Google Cloud Natural Language Service.", e);
}
// Return the entities mentioned.
return response.getEntitiesList().stream().map(Entity::getName).collect(Collectors.toList());
}
}
package com.squaretest.demo17;
import com.google.api.gax.rpc.ApiException;
import com.google.cloud.language.v1.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class LanguageAnalyzerTest {
@Mock
private LanguageServiceClient mockLanguageService;
private LanguageAnalyzer languageAnalyzerUnderTest;
@BeforeEach
void setUp() {
languageAnalyzerUnderTest = new LanguageAnalyzer(mockLanguageService);
}
@Test
void testGetEntitiesMentioned() throws Exception {
// Setup
// Configure LanguageServiceClient.analyzeEntities(...).
final AnalyzeEntitiesResponse analyzeEntitiesResponse = AnalyzeEntitiesResponse.newBuilder()
.addEntities(Entity.newBuilder()
.setName("name")
.build())
.build();
when(mockLanguageService.analyzeEntities(AnalyzeEntitiesRequest.newBuilder()
.setDocument(Document.newBuilder()
.setType(Document.Type.PLAIN_TEXT)
.setContent("value")
.build())
.setEncodingType(EncodingType.UTF16)
.build())).thenReturn(analyzeEntitiesResponse);
// Run the test
final List<String> result = languageAnalyzerUnderTest.getEntitiesMentioned("text");
// Verify the results
assertEquals(List.of("value"), result);
}
@Test
void testGetEntitiesMentioned_LanguageServiceClientThrowsApiException() {
// Setup
when(mockLanguageService.analyzeEntities(AnalyzeEntitiesRequest.newBuilder()
.setDocument(Document.newBuilder()
.setType(Document.Type.PLAIN_TEXT)
.setContent("value")
.build())
.setEncodingType(EncodingType.UTF16)
.build())).thenThrow(ApiException.class);
// Run the test
assertThrows(LanguageServiceException.class, () -> languageAnalyzerUnderTest.getEntitiesMentioned("text"));
}
}
Spring Rest Controller
The source class is a rest controller that retrieves deals from a deals service and returns them in JSON form to the requester. The test class generated by Squaretest contains tests for the following scenarios.- The primary flow where the deals service returns one item.
- The alternate flow where the deals service returns no items.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
package com.squaretest.demo4;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
@RestController
@RequestMapping(path = "/deals", produces = MediaType.APPLICATION_JSON_VALUE)
public class DealsController {
private final DealsProvider dealsProvider;
private final MetricAdapter metricAdapter;
public DealsController(
final DealsProvider dealsProvider,
final MetricAdapter metricAdapter) {
this.dealsProvider = dealsProvider;
this.metricAdapter = metricAdapter;
}
@GetMapping("/current")
public List<Deal> getCurrentDeals(@RequestParam(name = "sortKey") final String sortKey) {
return safeGetDeals(sortKey);
}
private List<Deal> safeGetDeals(final String sortKey) {
try {
final List<Deal> deals = dealsProvider.getCurrentDeals(sortKey);
metricAdapter.recordDealsRetrieved(sortKey);
return deals;
} catch (final NetworkException e) {
metricAdapter.recordNetworkException(sortKey, e);
return Collections.emptyList();
} catch (final ServiceException e) {
metricAdapter.recordServiceException(sortKey, e);
return Collections.emptyList();
}
}
}
package com.squaretest.demo4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@WebMvcTest(DealsController.class)
class DealsControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private DealsProvider mockDealsProvider;
@MockBean
private MetricAdapter mockMetricAdapter;
@Test
void testGetCurrentDeals() throws Exception {
// Setup
// Configure DealsProvider.getCurrentDeals(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
final List<Deal> deals = List.of(deal);
when(mockDealsProvider.getCurrentDeals("sortKey")).thenReturn(deals);
// Run the test and verify the results
mockMvc.perform(get("/deals/current")
.param("sortKey", "sortKey")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json("{}", true));
verify(mockMetricAdapter).recordDealsRetrieved("sortKey");
}
@Test
void testGetCurrentDeals_DealsProviderReturnsNoItems() throws Exception {
// Setup
when(mockDealsProvider.getCurrentDeals("sortKey")).thenReturn(Collections.emptyList());
// Run the test and verify the results
mockMvc.perform(get("/deals/current")
.param("sortKey", "sortKey")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json("[]", true));
verify(mockMetricAdapter).recordDealsRetrieved("sortKey");
}
@Test
void testGetCurrentDeals_DealsProviderThrowsNetworkException() throws Exception {
// Setup
when(mockDealsProvider.getCurrentDeals("sortKey")).thenThrow(NetworkException.class);
// Run the test and verify the results
mockMvc.perform(get("/deals/current")
.param("sortKey", "sortKey")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json("[]", true));
verify(mockMetricAdapter).recordNetworkException(eq("sortKey"), any(NetworkException.class));
}
@Test
void testGetCurrentDeals_DealsProviderThrowsServiceException() throws Exception {
// Setup
when(mockDealsProvider.getCurrentDeals("sortKey")).thenThrow(ServiceException.class);
// Run the test and verify the results
mockMvc.perform(get("/deals/current")
.param("sortKey", "sortKey")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json("[]", true));
verify(mockMetricAdapter).recordServiceException(eq("sortKey"), any(ServiceException.class));
}
}
Spring Website Controller
The source class is a controller that renders pages allowing admin users to view and create deals. Squaretest generated the following tests for the List Deals page.- The primary flow where the deals service returns one item.
- The alternate flow where the deals service returns no items.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
- The primary flow where the new deal is created successfully.
- The alternate flow where the deals service returns an error.
- The alternate flow where the connection to the deals service was interrupted.
package com.squaretest.demo5;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@Controller
@RequestMapping(path = "/admin/deals")
public class DealsController {
private static final Logger Log = Logger.getLogger(DealsController.class.getName());
private final DealsStore dealsStore;
public DealsController(
final DealsStore dealsStore) {
this.dealsStore = dealsStore;
}
@GetMapping
public String list(Model model) throws NetworkException, ServiceException {
model.addAttribute("deals", getDeals());
return "admin/deals/index";
}
@GetMapping("/new")
public String newDeal(Model model) {
DealForm emptyDeal = new DealForm();
model.addAttribute("deal", emptyDeal);
return "admin/deals/new";
}
@PostMapping("/new")
public String createNewDeal(@Valid DealForm dealForm, Model model) throws NetworkException, ServiceException {
Deal deal = new Deal();
mapProperties(dealForm, deal);
try {
this.dealsStore.save(deal);
} catch (NetworkException | ServiceException e) {
Log.log(Level.SEVERE, "Exception saving deal", e);
throw e;
}
return "redirect:/admin/deals";
}
private List<Deal> getDeals() throws NetworkException, ServiceException {
try {
return dealsStore.getCurrentDeals();
} catch (final NetworkException | ServiceException e) {
Log.log(Level.SEVERE, "Exception retrieving deals from deals service", e);
throw e;
}
}
private static void mapProperties(final DealForm dealForm, final Deal deal) {
deal.setId(dealForm.getId());
deal.setProductName(dealForm.getProductName());
deal.setPrice(dealForm.getPrice());
deal.setQuantityRemaining(dealForm.getQuantityRemaining());
deal.setImageUrl(dealForm.getImageUrl());
}
}
package com.squaretest.demo5;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@WebMvcTest(DealsController.class)
class DealsControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private DealsStore mockDealsStore;
@Test
void testList() throws Exception {
// Setup
// Configure DealsStore.getCurrentDeals(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
final List<Deal> deals = List.of(deal);
when(mockDealsStore.getCurrentDeals()).thenReturn(deals);
// Run the test and verify the results
mockMvc.perform(get("/admin/deals")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
}
@Test
void testList_DealsStoreReturnsNoItems() throws Exception {
// Setup
when(mockDealsStore.getCurrentDeals()).thenReturn(Collections.emptyList());
// Run the test and verify the results
mockMvc.perform(get("/admin/deals")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
}
@Test
void testList_DealsStoreThrowsNetworkException() throws Exception {
// Setup
when(mockDealsStore.getCurrentDeals()).thenThrow(NetworkException.class);
// Run the test and verify the results
mockMvc.perform(get("/admin/deals")
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andExpect(content().string("expectedResponse"));
}
@Test
void testList_DealsStoreThrowsServiceException() throws Exception {
// Setup
when(mockDealsStore.getCurrentDeals()).thenThrow(ServiceException.class);
// Run the test and verify the results
mockMvc.perform(get("/admin/deals")
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andExpect(content().string("expectedResponse"));
}
@Test
void testNewDeal() throws Exception {
// Setup
// Run the test and verify the results
mockMvc.perform(get("/admin/deals/new")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
}
@Test
void testCreateNewDeal() throws Exception {
// Setup
// Run the test and verify the results
final MockHttpServletResponse response = mockMvc.perform(post("/admin/deals/new")
.param("id", "id")
.param("productName", "productName")
.param("price", "0")
.param("quantityRemaining", "0")
.param("imageUrl", "imageUrl")
.with(csrf())
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
// Confirm DealsStore.save(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
verify(mockDealsStore).save(deal);
}
@Test
void testCreateNewDeal_DealsStoreThrowsNetworkException() throws Exception {
// Setup
// Configure DealsStore.save(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
doThrow(NetworkException.class).when(mockDealsStore).save(deal);
// Run the test and verify the results
final MockHttpServletResponse response = mockMvc.perform(post("/admin/deals/new")
.param("id", "id")
.param("productName", "productName")
.param("price", "0")
.param("quantityRemaining", "0")
.param("imageUrl", "imageUrl")
.with(csrf())
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andExpect(content().string("expectedResponse"));
}
@Test
void testCreateNewDeal_DealsStoreThrowsServiceException() throws Exception {
// Setup
// Configure DealsStore.save(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
doThrow(ServiceException.class).when(mockDealsStore).save(deal);
// Run the test and verify the results
final MockHttpServletResponse response = mockMvc.perform(post("/admin/deals/new")
.param("id", "id")
.param("productName", "productName")
.param("price", "0")
.param("quantityRemaining", "0")
.param("imageUrl", "imageUrl")
.with(csrf())
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andExpect(content().string("expectedResponse"));
}
}
Spring Website Controller Async
The source class is a controller that renders the index page for an ecommerce website. The controller needs to make service calls to load the customer's most recent orders as well as the deals for that particular day. The controller makes the service calls in separate threads, so they can run in parallel and reduce page load time. Squaretest creates tests for the following cases.- The primary flow where the deals service and order service both return one item.
- The alternate flow where the deals service returns no items.
- The alternate flow where the deals service returns an error.
- The alternate flow where the order service returns no items.
- The alternate flow where the order service returns an error.
package com.squaretest.demo10;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
@Controller
@RequestMapping(path = "/")
public class IndexController {
private static final Logger Log = Logger.getLogger(IndexController.class.getName());
private final DealsServiceAsync dealsService;
private final OrdersServiceAsync ordersService;
private final MetricAdapter metricAdapter;
public IndexController(
final DealsServiceAsync dealsService,
final OrdersServiceAsync ordersService,
final MetricAdapter metricAdapter) {
this.dealsService = dealsService;
this.ordersService = ordersService;
this.metricAdapter = metricAdapter;
}
@GetMapping
public String index(final Model model) {
// Perform the service calls in parallel in background threads.
final CompletableFuture<List<Deal>> dealsFuture = dealsService.getDeals();
final CompletableFuture<List<Order>> recentOrdersFuture = ordersService.getRecentOrders(getCustomerId());
// Wait for the calls to complete, and add the results to the model.
try {
model.addAttribute("deals", dealsFuture.get());
Log.info("getDealsCall() call succeeded.");
metricAdapter.recordGetDealsCallSuccess();
} catch (ExecutionException | InterruptedException e) {
metricAdapter.recordGetDealsException(e);
Log.log(Level.WARNING, "Exception querying deals service", e);
}
try {
model.addAttribute("recentOrders", recentOrdersFuture.get());
Log.info("getRecentOrders() call succeeded.");
metricAdapter.recordGetRecentOrdersCallSuccess();
} catch (final ExecutionException | InterruptedException e) {
Log.log(Level.WARNING, "Exception querying ordering service", e);
metricAdapter.recordGetRecentOrdersException(e);
}
return "index";
}
private String getCustomerId() {
// Omitted: the authentication logic.
return "customerId";
}
}
package com.squaretest.demo10;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@WebMvcTest(IndexController.class)
class IndexControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private DealsServiceAsync mockDealsService;
@MockBean
private OrdersServiceAsync mockOrdersService;
@MockBean
private MetricAdapter mockMetricAdapter;
@Test
void testIndex() throws Exception {
// Setup
// Configure DealsServiceAsync.getDeals(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
final CompletableFuture<List<Deal>> listCompletableFuture = CompletableFuture.completedFuture(List.of(deal));
when(mockDealsService.getDeals()).thenReturn(listCompletableFuture);
// Configure OrdersServiceAsync.getRecentOrders(...).
final Order order = new Order();
order.setId("id");
order.setShipAddress("shipAddress");
order.setShipDate(LocalDateTime.of(2020, 1, 1, 0, 0, 0, 0).toInstant(ZoneOffset.UTC));
final Product product = new Product();
product.setId("id");
order.setProducts(List.of(product));
final CompletableFuture<List<Order>> listCompletableFuture1 = CompletableFuture.completedFuture(List.of(order));
when(mockOrdersService.getRecentOrders("customerId")).thenReturn(listCompletableFuture1);
// Run the test and verify the results
mockMvc.perform(get("/")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
verify(mockMetricAdapter).recordGetDealsCallSuccess();
verify(mockMetricAdapter).recordGetRecentOrdersCallSuccess();
}
@Test
void testIndex_DealsServiceAsyncReturnsNoItems() throws Exception {
// Setup
// Configure DealsServiceAsync.getDeals(...).
final CompletableFuture<List<Deal>> listCompletableFuture = CompletableFuture.completedFuture(
Collections.emptyList());
when(mockDealsService.getDeals()).thenReturn(listCompletableFuture);
// Configure OrdersServiceAsync.getRecentOrders(...).
final Order order = new Order();
order.setId("id");
order.setShipAddress("shipAddress");
order.setShipDate(LocalDateTime.of(2020, 1, 1, 0, 0, 0, 0).toInstant(ZoneOffset.UTC));
final Product product = new Product();
product.setId("id");
order.setProducts(List.of(product));
final CompletableFuture<List<Order>> listCompletableFuture1 = CompletableFuture.completedFuture(List.of(order));
when(mockOrdersService.getRecentOrders("customerId")).thenReturn(listCompletableFuture1);
// Run the test and verify the results
mockMvc.perform(get("/")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
verify(mockMetricAdapter).recordGetDealsCallSuccess();
verify(mockMetricAdapter).recordGetRecentOrdersCallSuccess();
}
@Test
void testIndex_DealsServiceAsyncReturnsFailure() throws Exception {
// Setup
// Configure DealsServiceAsync.getDeals(...).
final CompletableFuture<List<Deal>> listCompletableFuture = CompletableFuture.failedFuture(
new Exception("message"));
when(mockDealsService.getDeals()).thenReturn(listCompletableFuture);
// Configure OrdersServiceAsync.getRecentOrders(...).
final Order order = new Order();
order.setId("id");
order.setShipAddress("shipAddress");
order.setShipDate(LocalDateTime.of(2020, 1, 1, 0, 0, 0, 0).toInstant(ZoneOffset.UTC));
final Product product = new Product();
product.setId("id");
order.setProducts(List.of(product));
final CompletableFuture<List<Order>> listCompletableFuture1 = CompletableFuture.completedFuture(List.of(order));
when(mockOrdersService.getRecentOrders("customerId")).thenReturn(listCompletableFuture1);
// Run the test and verify the results
mockMvc.perform(get("/")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
verify(mockMetricAdapter).recordGetDealsException(any(Exception.class));
verify(mockMetricAdapter).recordGetRecentOrdersCallSuccess();
}
@Test
void testIndex_OrdersServiceAsyncReturnsNoItems() throws Exception {
// Setup
// Configure DealsServiceAsync.getDeals(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
final CompletableFuture<List<Deal>> listCompletableFuture = CompletableFuture.completedFuture(List.of(deal));
when(mockDealsService.getDeals()).thenReturn(listCompletableFuture);
// Configure OrdersServiceAsync.getRecentOrders(...).
final CompletableFuture<List<Order>> listCompletableFuture1 = CompletableFuture.completedFuture(
Collections.emptyList());
when(mockOrdersService.getRecentOrders("customerId")).thenReturn(listCompletableFuture1);
// Run the test and verify the results
mockMvc.perform(get("/")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
verify(mockMetricAdapter).recordGetDealsCallSuccess();
verify(mockMetricAdapter).recordGetRecentOrdersCallSuccess();
}
@Test
void testIndex_OrdersServiceAsyncReturnsFailure() throws Exception {
// Setup
// Configure DealsServiceAsync.getDeals(...).
final Deal deal = new Deal();
deal.setId("id");
deal.setProductName("productName");
deal.setPrice(new BigDecimal("0.00"));
deal.setQuantityRemaining(0);
deal.setImageUrl("imageUrl");
final CompletableFuture<List<Deal>> listCompletableFuture = CompletableFuture.completedFuture(List.of(deal));
when(mockDealsService.getDeals()).thenReturn(listCompletableFuture);
// Configure OrdersServiceAsync.getRecentOrders(...).
final CompletableFuture<List<Order>> listCompletableFuture1 = CompletableFuture.failedFuture(
new Exception("message"));
when(mockOrdersService.getRecentOrders("customerId")).thenReturn(listCompletableFuture1);
// Run the test and verify the results
mockMvc.perform(get("/")
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("expectedResponse"));
verify(mockMetricAdapter).recordGetDealsCallSuccess();
verify(mockMetricAdapter).recordGetRecentOrdersException(any(Exception.class));
}
}
Utils Class
The source class is a StringUtils class that contains methods for working with Java Strings. Squaretest generated a test class containing a simple test method for replaceFirst(..). The simple test method contains assertion statements that cover the following cases.- The primary flow.
- The alternate flow where the regex is invalid. Squaretest inferred this case by reading the @throws tag in the Javadocs.
package com.squaretest.demo6;
public class StringUtils {
/**
* This is copied from org.apache.commons.lang3.RegExUtils.
* <p>Replaces the first substring of the text string that matches the given regular expression
* with the given replacement.</p>
*
* @param text text to search and replace in, may be null
* @param regex the regular expression to which this string is to be matched
* @param replacement the string to be substituted for the first match
* @return the text with the first replacement processed,
* {@code null} if null String input
*
* @throws java.util.regex.PatternSyntaxException
* if the regular expression's syntax is invalid
*
*/
public static String replaceFirst(final String text, final String regex, final String replacement) {
if (text == null || regex == null || replacement == null ) {
return text;
}
return text.replaceFirst(regex, replacement);
}
}
package com.squaretest.demo6;
import org.junit.jupiter.api.Test;
import java.util.regex.PatternSyntaxException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class StringUtilsTest {
@Test
void testReplaceFirst() {
assertEquals("text", StringUtils.replaceFirst("text", "regex", "replacement"));
assertThrows(PatternSyntaxException.class, () -> StringUtils.replaceFirst("text", "regex", "replacement"));
}
}
Static Factory Methods
The source class is a Uri class that represents a website Uri. The Uri is instantiated by invoking the static factory method: parse(..). This is similar to the sealed abstract class pattern used in the Android Uri class.Squaretest generates special tests for the static factory methods. Each test method uses the static factory method to construct the source class, then invokes all getter methods and compares their returned values in assertEquals(..) calls.
package com.squaretest.demo7;
import java.util.Map;
public abstract class Uri {
private final String schema;
private final String authority;
private final String path;
private final Map<String, String> queryParams;
private Uri(
final String schema,
final String authority,
final String path,
final Map<String, String> queryParams) {
this.schema = schema;
this.authority = authority;
this.path = path;
this.queryParams = queryParams;
}
public static Uri parse(final String theUri) throws UriParseException {
// Actual parsing code omitted.
return new Uri("schema", "authority", "path", Map.of()){};
}
public String getSchema() {
return schema;
}
public String getAuthority() {
return authority;
}
public String getPath() {
return path;
}
public Map<String, String> getQueryParams() {
return queryParams;
}
}
package com.squaretest.demo7;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UriTest {
@Test
void testParse() throws Exception {
// Run the test
final Uri result = Uri.parse("theUri");
assertEquals("schema", result.getSchema());
assertEquals("authority", result.getAuthority());
assertEquals("path", result.getPath());
assertEquals(Map.ofEntries(Map.entry("value", "value")), result.getQueryParams());
}
@Test
void testParse_ThrowsUriParseException() {
// Setup
// Run the test
assertThrows(UriParseException.class, () -> Uri.parse("theUri"));
}
}
Enum
The source class is the JavaVersion enum copied from Apache Commons Lang 3. It provides APIs for determining the version of the current JVM and comparing it to other Java versions.Squaretest generates tests for each instance method in the enum. Each test invokes the source method on each value in the enum and compares the result to an expected value. Squaretest also generates tests for the static methods in the enum.
/*
* This is copied from org.apache.commons.lang3.JavaVersion in Apache Commons Lang 3.12.
* See https://commons.apache.org/proper/commons-lang/.
*/
package com.squaretest.demo19;
import org.apache.commons.lang3.math.NumberUtils;
/**
* <p>An enum representing all the versions of the Java specification.
* This is intended to mirror available values from the
* <em>java.specification.version</em> System property. </p>
*
* @since 3.0
*/
public enum JavaVersion {
/**
* The Java version reported by Android. This is not an official Java version number.
*/
JAVA_0_9(1.5f, "0.9"),
/**
* Java 1.1.
*/
JAVA_1_1(1.1f, "1.1"),
/**
* Java 1.2.
*/
JAVA_1_2(1.2f, "1.2"),
/**
* Java 1.3.
*/
JAVA_1_3(1.3f, "1.3"),
/**
* Java 1.4.
*/
JAVA_1_4(1.4f, "1.4"),
/**
* Java 1.5.
*/
JAVA_1_5(1.5f, "1.5"),
/**
* Java 1.6.
*/
JAVA_1_6(1.6f, "1.6"),
/**
* Java 1.7.
*/
JAVA_1_7(1.7f, "1.7"),
/**
* Java 1.8.
*/
JAVA_1_8(1.8f, "1.8"),
/**
* Java 1.9.
*
* @deprecated As of release 3.5, replaced by {@link #JAVA_9}
*/
@Deprecated
JAVA_1_9(9.0f, "9"),
/**
* Java 9.
*
* @since 3.5
*/
JAVA_9(9.0f, "9"),
/**
* Java 10.
*
* @since 3.7
*/
JAVA_10(10.0f, "10"),
/**
* Java 11.
*
* @since 3.8
*/
JAVA_11(11.0f, "11"),
/**
* Java 12.
*
* @since 3.9
*/
JAVA_12(12.0f, "12"),
/**
* Java 13.
*
* @since 3.9
*/
JAVA_13(13.0f, "13"),
/**
* Java 14.
*
* @since 3.11
*/
JAVA_14(14.0f, "14"),
/**
* Java 15.
*
* @since 3.11
*/
JAVA_15(15.0f, "15"),
/**
* Java 16.
*
* @since 3.11
*/
JAVA_16(16.0f, "16"),
/**
* Java 17.
*
* @since 3.12.0
*/
JAVA_17(17.0f, "17"),
/**
* The most recent java version. Mainly introduced to avoid to break when a new version of Java is used.
*/
JAVA_RECENT(maxVersion(), Float.toString(maxVersion()));
/**
* The float value.
*/
private final float value;
/**
* The standard name.
*/
private final String name;
/**
* Constructor.
*
* @param value the float value
* @param name the standard name, not null
*/
JavaVersion(final float value, final String name) {
this.value = value;
this.name = name;
}
/**
* <p>Whether this version of Java is at least the version of Java passed in.</p>
*
* <p>For example:<br>
* {@code myVersion.atLeast(JavaVersion.JAVA_1_4)}<p>
*
* @param requiredVersion the version to check against, not null
* @return true if this version is equal to or greater than the specified version
*/
public boolean atLeast(final JavaVersion requiredVersion) {
return this.value >= requiredVersion.value;
}
/**
* <p>Whether this version of Java is at most the version of Java passed in.</p>
*
* <p>For example:<br>
* {@code myVersion.atMost(JavaVersion.JAVA_1_4)}<p>
*
* @param requiredVersion the version to check against, not null
* @return true if this version is equal to or greater than the specified version
* @since 3.9
*/
public boolean atMost(final JavaVersion requiredVersion) {
return this.value <= requiredVersion.value;
}
/**
* Transforms the given string with a Java version number to the
* corresponding constant of this enumeration class. This method is used
* internally.
*
* @param nom the Java version as string
* @return the corresponding enumeration constant or <b>null</b> if the
* version is unknown
*/
// helper for static importing
static JavaVersion getJavaVersion(final String nom) {
return get(nom);
}
/**
* Transforms the given string with a Java version number to the
* corresponding constant of this enumeration class. This method is used
* internally.
*
* @param versionStr the Java version as string
* @return the corresponding enumeration constant or <b>null</b> if the
* version is unknown
*/
static JavaVersion get(final String versionStr) {
if (versionStr == null) {
return null;
}
switch (versionStr) {
case "0.9":
return JAVA_0_9;
case "1.1":
return JAVA_1_1;
case "1.2":
return JAVA_1_2;
case "1.3":
return JAVA_1_3;
case "1.4":
return JAVA_1_4;
case "1.5":
return JAVA_1_5;
case "1.6":
return JAVA_1_6;
case "1.7":
return JAVA_1_7;
case "1.8":
return JAVA_1_8;
case "9":
return JAVA_9;
case "10":
return JAVA_10;
case "11":
return JAVA_11;
case "12":
return JAVA_12;
case "13":
return JAVA_13;
case "14":
return JAVA_14;
case "15":
return JAVA_15;
case "16":
return JAVA_16;
case "17":
return JAVA_17;
default:
final float v = toFloatVersion(versionStr);
if ((v - 1.) < 1.) { // then we need to check decimals > .9
final int firstComma = Math.max(versionStr.indexOf('.'), versionStr.indexOf(','));
final int end = Math.max(versionStr.length(), versionStr.indexOf(',', firstComma));
if (Float.parseFloat(versionStr.substring(firstComma + 1, end)) > .9f) {
return JAVA_RECENT;
}
} else if (v > 10) {
return JAVA_RECENT;
}
return null;
}
}
/**
* <p>The string value is overridden to return the standard name.</p>
*
* <p>For example, {@code "1.5"}.</p>
*
* @return the name, not null
*/
@Override
public String toString() {
return name;
}
/**
* Gets the Java Version from the system or 99.0 if the {@code java.specification.version} system property is not set.
*
* @return the value of {@code java.specification.version} system property or 99.0 if it is not set.
*/
private static float maxVersion() {
final float v = toFloatVersion(System.getProperty("java.specification.version", "99.0"));
if (v > 0) {
return v;
}
return 99f;
}
/**
* Parses a float value from a String.
*
* @param value the String to parse.
* @return the float value represented by the string or -1 if the given String can not be parsed.
*/
private static float toFloatVersion(final String value) {
final int defaultReturnValue = -1;
if (!value.contains(".")) {
return NumberUtils.toFloat(value, defaultReturnValue);
}
final String[] toParse = value.split("\\.");
if (toParse.length >= 2) {
return NumberUtils.toFloat(toParse[0] + '.' + toParse[1], defaultReturnValue);
}
return defaultReturnValue;
}
}
package com.squaretest.demo19;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
class JavaVersionTest {
@Test
void testAtLeast() {
assertFalse(JavaVersion.JAVA_0_9.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_1.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_2.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_3.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_4.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_5.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_6.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_7.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_8.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_9.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_9.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_10.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_11.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_12.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_13.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_14.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_15.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_16.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_17.atLeast(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_RECENT.atLeast(JavaVersion.JAVA_0_9));
}
@Test
void testAtMost() {
assertFalse(JavaVersion.JAVA_0_9.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_1.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_2.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_3.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_4.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_5.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_6.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_7.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_8.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_1_9.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_9.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_10.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_11.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_12.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_13.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_14.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_15.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_16.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_17.atMost(JavaVersion.JAVA_0_9));
assertFalse(JavaVersion.JAVA_RECENT.atMost(JavaVersion.JAVA_0_9));
}
@Test
void testGetJavaVersion() {
assertEquals(JavaVersion.JAVA_0_9, JavaVersion.getJavaVersion("nom"));
}
@Test
void testGet() {
assertEquals(JavaVersion.JAVA_0_9, JavaVersion.get("versionStr"));
}
@Test
void testToString() {
assertEquals("name", JavaVersion.JAVA_0_9.toString());
assertEquals("name", JavaVersion.JAVA_1_1.toString());
assertEquals("name", JavaVersion.JAVA_1_2.toString());
assertEquals("name", JavaVersion.JAVA_1_3.toString());
assertEquals("name", JavaVersion.JAVA_1_4.toString());
assertEquals("name", JavaVersion.JAVA_1_5.toString());
assertEquals("name", JavaVersion.JAVA_1_6.toString());
assertEquals("name", JavaVersion.JAVA_1_7.toString());
assertEquals("name", JavaVersion.JAVA_1_8.toString());
assertEquals("name", JavaVersion.JAVA_1_9.toString());
assertEquals("name", JavaVersion.JAVA_9.toString());
assertEquals("name", JavaVersion.JAVA_10.toString());
assertEquals("name", JavaVersion.JAVA_11.toString());
assertEquals("name", JavaVersion.JAVA_12.toString());
assertEquals("name", JavaVersion.JAVA_13.toString());
assertEquals("name", JavaVersion.JAVA_14.toString());
assertEquals("name", JavaVersion.JAVA_15.toString());
assertEquals("name", JavaVersion.JAVA_16.toString());
assertEquals("name", JavaVersion.JAVA_17.toString());
assertEquals("name", JavaVersion.JAVA_RECENT.toString());
}
}
Forum
The Squaretest forum has moved to GitHub Discussions!Legacy Forum
The legacy forum is available at the Legacy Forum Archive.Report Bugs
Licenses Are Perpetual
Both licenses are perpetual, meaning they never expire.Individual vs Business
An individual license has your name on it. You can use it to install Squaretest on any device on which you are the primary user. A business license has the company name on it as well as the number of users who may use the license. The license may be used by the given number of users. Each user may use the license on as many company devices as he or she likes.Free Trial
You can try Squaretest for free for 30 days. Please follow the instructions in the user guide to install the plugin and begin the trial.Offline License Validation
Squaretest licenses are validated offline. They can be used in environments that are not connected to the internet.Purchase Justification
Developers may need to convince managers or other stakeholders that the license purchase is justified. The following argument shows how the developer time savings alone could justify the purchase.Assumptions
- The cost to hire a developer for 1 year is $138,229.92.
- The average developer works 8 hours per day and has 3-weeks (15 business days) of paid vacation/PTO and 7 national holidays per year.
- There are 260 weekdays per year.
- Squaretest saves the developer 12 minutes of time each time he/she creates a new test class for a standard Java component.
Calculations
- The cost of 1 developer-day is $580.80 = $138,229.92 / (260 - 15 - 7).
- The cost of 1 developer-hour is $72.60 = $580.80 / 8.
- Number of hours needed for Squaretest to pay for itself 0.76 hours = 55 / 72.60.
- Number of new test classes for standard components needed to pay for itself: 3.8 = 0.76 / 0.2
- Squaretest will pay for itself when the user creates 4 new test classes for standard Java components.
Notes
Frequently Asked Questions
Which version of the Velocity Engine does Squaretest use to create the tests?
Squaretest uses a fork of version 2.0 of the Apache Velocity Engine.Does Squaretest collect usage metrics?
There are two build variants for Squaretest. The user experience regarding usage data collection varies in each version.Normal Squaretest Build
The normal Squaretest build is the version of Squaretest that is installed by default when you install Squaretest from the IntelliJ plugin repository.In this build, the first time you generate a test, Squaretest will ask you to allow the anonymous collection of usage data. The data helps us identify problems with Squaretest and prioritize bug-fixes and improvements. You can enable or disable the collection of usage metrics in the Squaretest settings menu at anytime. See Usage Data for more details.
No Telemetry Build
In the No Telemetry build, the code to transmit usage data is removed from Squaretest. Users cannot enable the anonymous collection of usage data. To install this build variant, follow the instructions on Usage Data.Does Squaretest send any data to the cloud?
Squaretest never sends your code to the cloud. Squaretest will anonymously send usage data to the cloud if you have allowed it as described above. Squaretest also sends requests to the licensing system; these requests include a unique identifier from your license. It does not make any other network requests.The one exception to this is if you create and use a Velocity template that makes a network request; i.e. create a Velocity template that uses code like $sourceClass.getClass().forName("java.net.URL").getConstructors() to construct an instance of java.net.URL, and then calls the openConnection() method on the URL object; using a template like that to create unit tests could cause Squaretest to make a network request.
Who stands behind Squaretest?
Squaretest LLC was founded by Nathan Shevick, a 6+ year software developer. Nathan worked for amazon.com for over 4 years before leaving to create Squaretest in 2017.Is Squaretest affiliated with Square, Inc?
No. Squaretest is not affiliated with Square, Inc. in any way.Where did the name Squaretest come from?
The Carpenter's Square is simple, easy-to-use and incredibly useful for carpentry and woodworking. Squaretest aims to be like the Carpenter's Square for writing unit tests.Terms and Conditions
The Squaretest plugin may be used in accordance with the following Terms and Conditions.Contact Us
Please use the following emails to contact us.- support@squaretest.com for support
- feedback@squaretest.com for feedback regarding Squaretest
- contact@squaretest.com for general questions