Entitymock DSL
Contents
Documentation
Introduction
Mock object
In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test.
Mock objects have the same interface as the real objects they mimic, allowing a client object to remain unaware of whether it is using a real object or a mock object. Many available mock object frameworks allow the programmer to specify which, and in what order, methods will be invoked on a mock object and what parameters will be passed to them, as well as what values will be returned. Thus, the behavior of a complex object such as a network socket can be mimicked by a mock object, allowing the programmer to discover whether the object being tested responds appropriately to the wide variety of states such mock objects may be in.
EntitymockDSL
In our implementation, we use a complex database, which would have to be initialized. If you do hand-entering data one by one, you will waste so much time to build up the volume and variety of data that we need. So we design to generate all mock objects for our database by initialization using entitymockDSL.
The main semantic elements of the EntitymockDSL are:
- mock entitymodel - the root element that contains all the other elements. A model can contain multiple mock entitymodels.
- import declarations - used to import external models or even Java classes.
- datainterchanges - define the imported datainterchange model to fill the mock data.
- resources - define all availabilities of a resource definition. Resources will be used as enum in objects or directly in the definition of mock entities.
- objects - contains consistent information for some kind of object definition. Objects are used as template for mock entities.
- mock entities - define the mocking rules of entities.
Mock entitymodel
mock entitymodel defines a set of mocking rules for an <imported entity model>, which has one or more entity definitions. Name of the mock entitymodel is defined according to the name of <imported entity model>, by just changing “entities.*” to “entitiesmock”.
A folder with the same name of the mock entitymodel name will be generated in folder /src-gen. several new java files will be auto-generated in this folder:
- EntityMockGenerator.java file.
- For each resource, a file named as “Resource”+<resource name>+“.java” will be generated.
- For each object, a file named as “Object”+<object name>+“.java” will be generated.
- For each element in mock entities, a file named as “Entity”+<mocking name>+“.java” will be generated.
► Syntax:
mock entitymodel for <imported entity model> {
[run with priority <priority number>]
import <import models/class name>
. . .
[datainterchanges {. . .}]
[resources {
resource <resouce name> {. . .}
. . .
}]
[objects {
object <object name> {. . .}
. . .
}]
mock entities {
mocking <mocking name> . . . {. . .}
. . .
}
}
Notes:
- The orientation entity model is defined as <imported entity model>, for which your mock entitymodel will fill the mocking data.
- priority is an optional definition, if more than 1 mock entitymodel package defined in one project, you can use this option to define the priority of filling mocking data. Default value is 10.
- As same as other dsl models, import declarations must be defined before other elements, all useful external models or java classes need to be import before using.
- datainterchanges, resources and objects are optional be defined before the definition of mock entities. The detail description of them will be introduced one by one in the next chapters.
► Example:
mock entitymodel for org.osbp.myfirstshop.entities.* {
run with priority 2
import java.util.Random
import org.osbp.myfirstshop.datainterchange.*
. . .
}
Notes:
- In this example, the mock entitymodel name is org.osbp.myfirstshop.entitiesmock.
Important definition
Some important definitions will be described here.
The first 2 definitions are basic definitions, which will be used in other definitions; the next 3 definitions are used in objects and the last 3 definitions are used in mock entities.
PropertyFillerType
PropertyFillerType is used to generate random mock data.
► It could be a random date Syntax 1:
future date <furtureYear number> years
past date <pastYear number> years
date in range <beginYear SingedNumber> up to and including <endYear SingedNumber> years
► Example 1:
date in range -50 up to and including -20 years
generates a random date in range from last 50 years to last 20 years
►or a random text Syntax 2:
text from (<text1> [<text2> . . .] )
paragraphs [<count number>]
sentences [<count number>]
words [<count number>]
► Example 2:
sentences 5
► or a random number Syntax 3:
boolean
signed double in range
[[<beginRange SingedDouble> | <entity attribute>] up to and including
<endRange SingedDouble> | <entity attribute>]
with <decimal number> decimals [round to <round double>]
signed double from (<signed double1> [<signed double2> . . .] )
signed integer in range
[[<beginRange SingedNumber> | <entity attribute>] up to and including
<endRange SingedNumber> |<entity attribute> ][round to <round number>]
signed integer from (<signed number1> [<signed number2> . . .] )
unsigned double in range [[<beginRange double> | <entity attribute>]
up to and including <endRange double> | <entity attribute>]
with <decimal number> decimals [round to <round double>]
unsigned double from (<double1> [<double2> . . .] )
unsigned integer in range [[<beginRange number> | <entity attribute>]
up to and including <endRange number> | <entity attribute> ]
[round to <round number>]
unsigned integer from (<number1> [<number2> . . .] )
► Example 3:
unsigned double in range 10000.0 up to and including 30000.0 with 2 decimals round to 500.0
generates a random unsigned double number between 9999 to 30001, with 2 decimal digits and round to 500, such as 13500.00 or 24500.00.
signed integer from( 3 8 11 )
generates a random integer number from the numbers in the set “( )”, in this case they are 3, 8 and 11.
signed double in range -10 up to and including 10 with 2 decimals
generates a random signed double number from -10.00 to 10.00 with 2 decimal digits and with no round, such as 3.15 or -7.98.
EntityMockObjectUsable
► EntityMockObjectUsable can be any of the object attribute <varXXX name> after var / embed in the following Syntax:
var <varFunction name> calculate as <jvmType name> based on ( [<jvmType name1> <EntityMockObjectUsable_1> [, <jvmType name2> <EntityMockObjectUsable_2>] . . . ] ) {<block expression>}
var <varEnum name> by enum <resource name>
var <varPlain name> (<var value1> [,] . . . )
var <varArray name> switch on <varEnum name> { when <resourceItem name> (<var value1> [,] . . . ) . . . }
embed <varEmbed name> defined as <object name>
var <varFill name> randomize <PropertyFillerType>
Notes:
- The definition of object attributes will be described in 2.2.2.4 and 2.2.2.5.
EntityMockObjectEnum
EntityMockObjectEnum defines a kind of object attribute by using a predefined resource.
► Syntax::
var <objectEnum name> by enum <resource name>
► Example:
resource GenderResources {
attributes( flag, description )
items {
MALE( "M" "male" )
FEMALE( "F" "female" )
}
}
. . .
object PersonObject {
var sex by enum GenderResources
. . .
}
Notes:
- In this example, a resource called GenderResources defined with 2 enum items: MALE and FEMALE; each of them has 2 attributes: flag and description; the flag of item MALE is “M” and its description is “male”, the flag of item FEMALE is “F” and its description is “female”.
- object Person has an attribute called sex, using resource GenderResources as the enum.
EntityMockObjectAttribute
EntityMockObjectAttribute are the definitions of object attribute.
► Syntax:
var <objectResource name> with <objectEnum name1>[.<resourceAttribute name>]
var <objectArray name> switch on <objectEnum name2> { when <resourceItem name> (<var value1> [,] . . . ) . . . }
var <objectPlain name> (<var value2> [,] . . . )
embed <objectEmbed name> defined as <object name1>
var <objectFill name> randomize <PropertyFillerType>
► Example:
object PersonObject {
var sex by enum GenderResources
var gender with sex.flag
var firstName switch on sex {
when MALE( "Andreas" "Armin" "Ernst" "Hans" "Hubert" "Jens" )
when FEMALE( "Andrea" "Evelin" "Jutta" "Maria" )
}
var mailProvider( "gmail.de" "yahoo.de" "mail.de" )
embed home_address defined as AddressObject
var age randomize signed integer in range 17 up to and including 90
. . .
}
Notes:
- In this example, the following attributes are defined:
- The attribute gender is defined as the attribute flag of enum sex by the 1st definition, which means gender can be “M” or “F”.
- The attribute firstName is defined with the 2nd definition, it is also using enum sex, if sex is MALE, firstName can be any of the names in the “( )” following MALE, for the situation of sex being FEMALE, using the same rule.
- The attribute mailProvider is defined with the 3rd definition. It can be one of the email providers in the following “( )”.
- The attribute home_address is defined directly with another object called AddressObject using the 4th definition. So it is an embed attribute using predefined object.
- The attribute age is defined as a random value with the last definition. The rule of generating random value is one of the options of PropertyFillerType which we have introduced in 2.2.2.1. In this case, attribute age is defined as a random signed integer; the value of it is between 17 and 90.
EntityMockObjectFunction
EntityMockObjectFunction defines the object attribute which will be calculated by java functions.
► Syntax:
var <objectFunction name> calculate as <jvmType name> based on (
[<jvmType name1> <EntityMockObjectUsable_1>
[, <jvmType name2> <EntityMockObjectUsable_2>]
. . . ] )
{<block expression>}
► Example:
object PersonObject {
var sex by enum GenderResources
var gender with sex.flag
var num_cars_owned randomize signed integer from( 3 8 11 )
. . .
var expenses_for_cars calculate as double based on(
String gender, int num_cars_owned ) {
var result = 0.0;
if( "M".equals( gender ) ) {result = num_cars_owned * 123.45}
else {result = 999.99}
return result
}
}
Notes:
- In this example, an object attribute called expense_for_cars is defined as a double value. The value will be calculated from the java function defined in the following “{ }”; 2 parameters are defined for this function; both of them are the object attributes in this object, one of them is gender which is a string value which is defined as “M” or “F” and the other is num_cars_owned which is an integer and its value will be a random integer as 3, 8 or 11.
EntityMockTemplate
EntityMockTemplate defines the mock template for mock entities by using a predefined object.
► Syntax:
template <template name> by object <object name>
► Example:
mocking mockedPerson for entity Person rows 20 to 50 {
template personData by object PersonObject
. . .
}
Notes:
- In this example, a template called personData is defined using object PersonObject.
EntityMockAttribute
EntityMockAttribute are the definitions of mocking entity attributes.
► Syntax:
var <entityAttribute name> as <template name>[[.]<objectEmbed name> . . .].<EntityMockObjectUsable>
var <entityAttribute name> randomize <PropertyFillerType>
ref <entityReference name> to existing entities | <mocking name> [optional for <optional number> percent]
- Each attribute and reference of the given entity except the cascade reference should be defined one by one. The <entityAttribute name> and <entityReference name> are as same as the names defined in given entity.
► Example:
objects {
object CompanyObject {
. . .
var position_title( "Store Manager" "HQ Finance" "Store Permanent Checker" )
. . .
}
object PersonObject {
. . .
embed employer defined as CompanyObject
. . .
}
. . .
}
. . .
mock entities {
mocking mockedDepartment for entity Department rows 10 to 20 {
. . .
}
mocking mockedPerson for entity Person rows 20 to 50 {
template personData by object PersonObject
var first_name as personData.firstName
var position as personData.employer.position_title
var description randomize sentences 5
ref warehouse to existing entities optional for 80 percent
ref department to mockedDepartment
. . .
}
}
Notes: In this example, the following attributes are defined:
- The attribute first _name and position are both defined with the 1st definition. first_name is defined as the attribute firstName of object PersonObject and position is defined as the attribute position_title of object CompanyObject which is defined as the embed attribute employer for object PersonObject.
- The attribute description is defined as a random value with the 2nd definition. The rule of generating random value is one of the options of PropertyFillerType which we have introduced in 2.2.2.1. In this case, attribute description is a string with 5 random sentences.
- The references warehouse and department are both defined with the last definition. warehouse is a reference of one of the existing entities warehouse whose data has been imported in datainterchanges and department is a reference of one of the predefined mock entities mockedDepartment. optional for 80 percent means the random value will be generated from 80% of the existing mocking data, without this option, the random value will be generated from 100% of the existing mocking data.
EntityMockFunction
EntityMockFunction defines the mocking entity attribute which will be calculated by java functions.
► Syntax:
var <entityAttribute name> calculate based on ([
<entityAttribute name11>
|<entityReference name12>[[.]<entityReference name12> . . .]
.<entityAttribute name12>
[, <entityAttribute name21>
|<entityReference name22>[[.]<entityReference name22> . . .]
.<entityAttribute name22>
. . . ]
]){<block expression>}
- The <entityAttribute name> and <entityReference name> are as same as the names defined in given entity.
► Example:
objects {
object DepartmentObject {
. . .
var default_yearly_income randomize unsigned double in range 10000.0 up to and including 30000.0 with 2 decimals round to 500.0
}
object PersonObject {
. . .
var yearly_income randomize unsigned double in range 10000.0 up to and including 30000.0 with 2 decimals round to 500.0
}
. . .
}
. . .
mock entities {
mocking mockedDepartment for entity Department rows 10 to 20 {
template departmentData by object DepartmentObject
var default_yearly_income as departmentData.default_yearly_income
. . .
}
. . .
mocking mockedPerson for entity Person rows 20 to 50 {
template personData by object PersonObject
var yearly_income as personData.yearly_income
. . .
ref department to mockedDepartment
. . .
var percentual_diff_to_default calculate based on
( yearly_income, department.default_yearly_income ) {
return yearly_income / department__default_yearly_income
}
}
}
Notes:
- In this example, an mocking entity attribute called percentual_diff_to_default is defined as a value which will be calculated from the java function defined in the following “{ }”; 2 parameters are defined for this function; one of them is yearly_income which is a mocking entity attribute, this attibute is defined as an attribute from template object PersonObject and the other is department.default_yearly_income, department is a reference mocking entity which is referred to mocking entity mockedDepartment, department.default_yearly_income is an attribute of this mocking entity, which is defined as an attribute from template object DepartmentObject.
datainterchanges
In this part, we use the predefined datainterchange models to fill the mock data. The datainterchange models are defined in *.data file in *.datainterchange folder.
► datainterchanges should be defined with the following Syntax in *.entitymock file:
datainterchanges {
datainterchange import <datainterchange name> from file <file URL>
. . .
}
► Example:
datainterchanges {
datainterchange import Warehouses from file
"file://E:/osbee_workspace/org.osbp.myfirstshop.model.entitymock/../org.osbp.myfirstshop.model.datainterchange/models/smooksresources/warehouses.xml"
. . .
}
Notes:
- You can define one or more imported datainterchange elements and the file path of their interchange files. This file can be different from the interchange file in *.data file.
resources
resources define all availabilities of a resource definition which will be used as enum in objects or directly in the definition of mock entities.
For each resource, a file named as “Resource”+<resource name>+“.java” will be generated in /src-gen/<mock entitymodel name> folder in your project.
► Syntax:
resources {
resource <resouce name>{
[attributes( <resourceAttribute name1> [,] . . .] )]
items { <reourceItem name> [(<resourceAttribute value1> [,] . . .)]
. . .
}
}
. . .
}
Notes:
- One or more resource could be defined in this part.
- resource should be defined with a <resouce name>.
- attributes of the resource is an optional definition. One or more attributes could be defined in the “( )” and could be divided with “ ” or “,”.
- items of the resource lists all availabilities of this resource. If no attributes defined, you should only list the item names; if the attributes is defined, the value of attribute for each item should be also defined in “( )” following item names and could be divided with “ ” or “,”.
► Example:
resources {
resource GenderResources {
attributes( flag, description )
items {
MALE( "M" "male" )
FEMALE( "F" "female" )
}
}
resource CompanyRelationResources {
attributes( name description )
items {
SUPPLIER( "supplier", "delivering interesting goods" )
CUSTOMER( "customer", "buying our interesting goods" )
}
}
resource MonthResources {
items {
JANUARY
FEBRUARY
MARCH
APRIL
MAY
JUNE
JULY
AUGUST
SEPTEMBER
OCTOBER
NOVEMBER
DECEMBER
}
}
}
objects
objects define the consistent information for some kind of definition such as person and address. objects are used as template for mock entities.
For each object, a file named as “Object”+<object name>+“.java” will be generated in /src-gen/<mock entitymodel name> folder in your project.
► Syntax:
objects {
object <object name>{
<''EntityMockObjectEnum''>
. . .
<''EntityMockObjectAttribute''>
. . .
<''EntityMockObjectFunction''>
. . .
}
. . .
}
Notes:
- One or more object could be defined in this part.
- Object should be defined with a <object name>.
- The details about EntityMockObjectEnum, EntityMockObjectAttribute and EntityMockObjectFunction are introduced in sections 2.2.2.3, 2.2.2.4 and 2.2.2.5.
► Example:
objects {
object AddressObject {
. . .
}
object DepartmentObject {
. . .
}
object PersonObject {
. . .
}
}
mock entities
mock entities define all rules of mocking data for given entities.
For each element in mock entities, a file named as “Entity”+<mocking name>+“.java” will be generated in /src-gen/<mock entitymodel name> folder in your project.
► Syntax:
mock entities {
mocking <mocking name> for entity <entity name>
1. rows <minRow number> to <maxRow number>{. . .}
2. by resource <resource name>{. . .}
3. iterate <entity attribute name> with
integer from <begin number> until <end number> step <step number>
| date from yesterday|today|tomorrow|<yyyy-mm-dd>
until yesterday|today|tomorrow|<yyyy-mm-dd>
every <step number> days|weeks|months|years
{. . .}
. . .
}
Notes:
- One or more mocking rules could be defined in this part.
- mocking rule should be defined with a <mocking name>.
- mocking rule should define for which entity this rule is used for.
There are 3 different ways to define the mocking rules; I will introduce them in the next sections.
mocking...rows...to...
The first way is generating the mocking data with random row number in a given range.
► Syntax:
mocking <mocking name> for entity <entity name>
rows <minRow number> to <maxRow number> {
<''EntityMockTemplate''>
. . .
<''EntityMockAttribute''>
. . .
<''EntityMockFunction''>
. . .
}
Notes:
- <minRow number> and <maxRow number> should be defined. And the data row numbers will be a random number between <minRow number> and <maxRow number>.
- The details about how to define the mocking entity attributes using EntityMockTemplate, EntityMockAttribute and EntityMockFunction are introduced in sections 2.2.2.6, 2.2.2.7 and 2.2.2.8.
► Example:
mock entities {
mocking mockedCompany for entity Company rows 5 to 10 {
. . .
}
mocking mockedPerson for entity Person rows 20 to 50 {
. . .
}
. . .
}
Notes:
In this example, 2 mocking rules are defined with a row number range. mocking rule mockedCompany is defined for entity Company, and the mocking data row number will be generated as a random value from 5 to 10, which means each time there will be generated 5 to 10 mocking companies; mocking rule mockedPerson is defined for entity Person, and the mocking data row number will be generated as a random value from 20 to 50, which means each time there will be generated 20 to 50 mocking persons.
mocking...by resource...
The second way is generating the mocking data by using predefined resource.
► Syntax:
mocking <mocking name> for entity <entity name> by resource <resource name>{
var <entityAttribute name> as <resourceAttribute name>
. . .
[createBlobMapping]
}
Notes:
- <resource name> must be referred.
- <entityAttribute name> is as same as the attribute name defined in given entity.
- <resourceAttribute name> is the attribute defined in referred resource.
- createBlobMapping is only used for some kind of file like image or pdf file, which could have different resolution and will be saved in the blob mapping using persistence unit “blob”.
► Example:
resources {
resource CurrencyResources {
attributes( code description )
items {
USD( "USD" "Dollar" )
EUR( "EUR" "Euro" )
}
}
resource resourceBlobMapping {
attributes (id, fileName, mimeTypeId, uniqueName)
items {
TOPOLOGY_DEU ("05fe5703-7768-492f-8ec3-33906f8a3b43", "deTopology.json", "6", "DEUTopology")
TOPOLOGY_USA ("771f3e8d-b0b7-43c9-b9a8-adf02a69165c", "usTopology.json", "6", "USATopology")
. . .
}
}
. . .
}
. . .
mock entities {
. . .
mocking currency for entity Currency by resource CurrencyResources {
var code as code
var description as description
}
mocking mockedBlobMapping for entity BlobMapping by resource resourceBlobMapping {
var id as id
var uniqueName as uniqueName
var fileName as fileName
var mimeTypeId as mimeTypeId
createBlobMapping
}
. . .
}
Notes:
In this example, 2 mocking rules are defined by using predefined resources. mocking rule currency is defined for entity Currency using resource CurrencyResources as enum, which means, the attribute code has a random value from “USD” and “EUR”; if it is “USD”, the value of attribute description will be “Dollar” and if the value of code is “EUR”, the value of attribute description will be “Euro”; mocking rule resourceBlobMapping is defined for entity BlobMapping using resource resourceBlobMapping as enum, the mocking data for attributes of entity will be generated randomly from the enum-values of attributes which are in resource listed. In this case, we are mocking to save images in the blob mapping, so the option createBlobMapping should be used here.
mocking...iterate with...
The last way is generating the mocking data with iteration rule.
► Syntax:
mocking <mocking name> for entity <entity name>
iterate <entity attribute name> with
1. integer from <begin number> until <end number> step <step number>
2. date from <begin date> until <end date> yesterday|today|tomorrow|<yyyy-mm-dd>
every <step number> days|weeks|months|years
{
<''EntityMockTemplate''>
. . .
<''EntityMockAttribute''>
. . .
<''EntityMockFunction''>
. . .
}
Notes:
- <entityAttribute name> is one of the attribute name defined in given entity.
- If this given entity attribute is defined as a number, iteration can be defined with range and step width. <begin number> and <end number> define the range of iteration. <step number> defines the step width. The iterate number begins with <begin number>; for each loop, the value of given entity attribute is assigned with the iterate number, all other values of entity attributes can be generated from this given attribute; for the next loop, the value of iterate number will be the last iterate number plus <step number>; loop will be end when iterate number greater than <end number>. So the number of mocking data rows will be the greatest integer less than (<end number> - <begin number>)/<step number>.
- If this given entity attribute is defined as date, the iterate date range and iterate step width will be given in this mocking data rule. <begin date> and <end date> can be defined as any value in this set ( yesterday, today, tomorrow, <yyyy-mm-dd>), and . <step number> defines the step width. The iterate date begins with <begin date>; for each loop, the value of given entity attribute is assigned with the iterate date, all other values of entity attributes can be generated from this given attribute; for the next loop, the iterate date will be the last iterate date plus <step number> days|weeks|months|years; loop will be end when iterate date later than <end date>.
- The details about how to define the mocking entity attributes using EntityMockTemplate, EntityMockAttribute and EntityMockFunction are introduced in sections 2.2.2.6, 2.2.2.7 and 2.2.2.8.
► Example:
mock entities {
. . .
mocking mockDailies for entity Dailies
iterate theDate with date from 2016 - 09 - 01 until yesterday every 1 days{
var dayOfMonth calculate based on( theDate ) {
return theDate.getDate
}
var monthOfYear calculate based on( theDate ) {
return theDate.month + 1
}
var theYear calculate based on( theDate ) {
return theDate.year + 1900
}
var quarter calculate based on( theDate ) {
return "Q" +( 1 +( ( theDate.month / 3 ) as int ) )
}
var theDay calculate based on( theDate ) {
return new java.text.SimpleDateFormat("E").format( theDate)
}
var theMonth calculate based on( theDate ) {
return new java.text.SimpleDateFormat("M").format( theDate )
}
var weekOfYear calculate based on( theDate ) {
return Integer.parseInt( new java.text.SimpleDateFormat("w").format( theDate ) )
}
}
. . .
}
Notes:
In this example, the mocking rules are defined with an iteration rule. mocking rule mockDailies is defined for entity Dailies, and entity attribute theDate is defined as the iterate date, the begin date is 2016-09-01, step is defined as 1 day. For each loop, all other entity attributes of entity Dailies will be calculated based on this iterate date; for the next loop, the value of new iterate date will be assigned as the next day of the last iterate date; when value of new iterate date is today, the loop will be break.
Copyright Notice
All rights are reserved by Compex Systemhaus GmbH. In particular, duplications, translations, microfilming, saving and processing in electronic systems are protected by copyright. Use of this manual is only authorized with the permission of Compex Systemhaus GmbH. Infringements of the law shall be punished in accordance with civil and penal laws. We have taken utmost care in putting together texts and images. Nevertheless, the possibility of errors cannot be completely ruled out. The Figures and information in this manual are only given as approximations unless expressly indicated as binding. Amendments to the manual due to amendments to the standard software remain reserved. Please note that the latest amendments to the manual can be accessed through our helpdesk at any time. The contractually agreed regulations of the licensing and maintenance of the standard software shall apply with regard to liability for any errors in the documentation. Guarantees, particularly guarantees of quality or durability can only be assumed for the manual insofar as its quality or durability are expressly stipulated as guaranteed. If you would like to make a suggestion, the Compex Team would be very pleased to hear from you.
(c) 2016-2024 Compex Systemhaus GmbH