mtedone / podam Goto Github PK
View Code? Open in Web Editor NEWPODAM - POjo DAta Mocker
Home Page: https://mtedone.github.io/podam
License: MIT License
PODAM - POjo DAta Mocker
Home Page: https://mtedone.github.io/podam
License: MIT License
As a Podam maintainer I want types to be manufactured by specialised classes so as to obtain the lowest possible coupling and the highest possible cohesion
Adding a @NotNull annotation to a Pojo attribute causes Podam not to fill that value. Although it's impossible to guarantee that Podam will create a value for an attribute annotated with @NotNull, e.g. for non-instantiable types, when a field is annotated with @NotNull Podam should behave as if that field was not annotated, e.g. follow default behaviour, which is to fill the possible fields with values anyway. This behaviour should also be documented because users must know that if they annotate a non instantiable attribute with @NotNull, validation will fail.
the URL
http://home.btconnect.com/jemosAgile/projects/podam/walk-through-example.html
contains the documentation is not accessible, it gives:
The requested URL was rejected. If you think this is an error, please contact the webmaster.
Your support ID is: 15891905563417259022
The website is lacking documentation on how to use AttributeMetadata with custom strategies.
Fixed in #24
public class BadClassUnitTest {
public static class BadClass {
private String name;
public BadClass() throws Exception { throw new Exception(); }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
}
/** The Podam Factory */
private PodamFactory factory = new PodamFactoryImpl();
@Test
public void testBadClass() {
BadClass pojo = factory.manufacturePojo(BadClass.class);
org.junit.Assert.assertNull(pojo);
}
}
java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1509)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:127)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:117)
at uk.co.jemos.podam.test.unit.BadClassUnitTest.testBadClass(BadClassUnitTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Is it possible to add functionality that recognizes JPA annotations and build Entity graph.
It would be nice to provide a mechanism where excluded attributes could be provided by the strategy without having to annotate them, perhaps by returning excluded attribute names.
Since specificTypes
is if of type Map<Class<?>, Class<?>
, every time you put something in it, it overwrites any previous insertions.
So for example, if I have this:
myFactory.addSpecific(MyAbstractClass.class, MyFirstSpecificClass.class);
myFactory.addSpecific(MyAbstractClass.class, MySecondSpecificClass.class);
The second invocation of the method overwrites the first, and MyAbstractClass
has only one concrete implementation added to it - the second one.
I think specificTypes
should be of type Map<Class<?>, List<Class<?>>>
.
With last versions the time to fill some objects with lists are very slow.
Now 21.262 sec
Before 3.123 sec
some mode to set default max limits in lists?
Podam should be intelligent enough to try the fullest constructor first, then if that doesn’t work, it should try the one with less arguments and so on until, if none of the other constructors work, it will choose the default one.
Example:
1: BigInteger(int bitLength, int certainty, Random rnd)
2: BigInteger(int signum, byte[] magnitude)
BigInteger(int numBits, Random rnd)
BigInteger(String val, int radix)
3: BigInteger(byte[] val)
BigInteger(String val)
Podam should start with 1. If it can’t build, the first constructor within 2 that succeeds should be used. If that doesn’t work, the fist constructor within 3 should be used and so on until the last choice should be the default constructor (if it exists). This is a very good test case that we should be writing when implement this strategy. The test cases should demonstrate Podam’s ability to “scale down” to the most useful (fullest) constructor up to the point the default constructor will be chosen (last choice).
Regards,
M.
PodamParameterizedType is in the main code, but I can only find it being used in tests. Is it part of the implementation, or just a test support class?
After commit 1c10708 it's impossible to exclude fields by name ass setter for exclusion names was removed.
podam-5.3.1.RELEASE
/uk/co/jemos/podam/api/PodamFactoryImpl.java:1839
Integer depth = pojos.get(realAttributeType);
if (depth == null) {
depth = -1;
}
if (depth <= strategy.getMaxDepth(pojo.getClass())) {
pojos.put(realAttributeType, depth + 1);, //<-- increment depth
attributeValue = this.manufacturePojoInternal(
realAttributeType, attributeMetadata, pojos, genericTypeArgsAll);
pojos.put(realAttributeType, depth);//<-- put -1 again
}
PodamFactoryImpl badly needs deconstructing into different classes, and it's methods broken down into smaller steps. The way it is now, it's very hard to maintain.
Hi,
When I try to manufacture pojo1 which contains pojo2 which contains pojo1, it throws a StackOverflowError. Maybe it is not an issue but I didn't find a way to prevent it.
There is a gist with unit test : https://gist.github.com/ludochane/5153343
Regards,
Ludovic
We often deal with classes that are not POJO
s in the strict sense of the word, but can very well be argued as ones.
Here's an example:
public class SpecialPojo {
private static class Holder {
private String holdingString;
private long holdingLong;
}
private Holder myHolder;
public SpecialPojo() {
myHolder = new Holder();
}
public String getMyString() {
return myHolder.holdingString;
}
public void setMyString(String myString) {
myHolder.holdingString = myString;
}
public long getMyLong() {
return myHolder.holdingLong;
}
public void setMyLong(long myLong) {
myHolder.holdingLong = myLong;
}
}
One would think this is one of the good, if not best, candidates PODAM
could weave its magic on to create a mock object with arbitrary values. But unfortunately, PODAM
won't fill this object with values since it doesn't strictly adhere to Java Bean
standards. If PODAM
was any less strict to not expect an explicit instance field matching the setter/getter, we'd have had an easier time mocking this type. These lines from the PodamUtils.java
are what holding PODAM
from being able to mock it:
public static ClassInfo getClassInfo(Class<?> clazz,
Set<Class<? extends Annotation>> excludeFieldAnnotations) {
Set<String> classFields = getDeclaredInstanceFields(clazz, excludeFieldAnnotations);
Set<Method> classSetters = getPojoSetters(clazz, classFields);
return new ClassInfo(clazz, classFields, classSetters);
}
Can PODAM
be enhanced to relax its definition of POJO
a bit so it will be able to handle such special cases of types that need mocking?
If someone invokes manufacturePojoWithFullData on Podamfactory and specifies an external factory as well, if Podam has to invoke the external factory, it doesn't invoke manufacturePojoWithFullData, rather manufacturePojo.
The major usage of random initialized objects is for testing, (I personally think) it's not a good idea to put podam annotation into pojos. If it allows to put the annotations on getters, the following would be possible:
class PetProxy extends Pet {
// podam annotation
public String getName() {... };
}
What do you think?
Hey Guys:
Again, great plugin. I'm having a peculiar issue running the plugin on my build system (codeship). My tests pass locally but, on Codeship, I get these errors:
Test set: com.xxxxx.api.services.CustomClientDetailsServiceImplUnitTest
-------------------------------------------------------------------------------
Tests run: 11, Failures: 0, Errors: 7, Skipped: 0, Time elapsed: 0.001 sec <<< F
AILURE! - in com.xxxxx.api.services.CustomClientDetailsServiceImplUnitTest
testAddClientDetailsThatIfRecordExistShouldThrowException(com.xxxxx.api.se
rvices.CustomClientDetailsServiceImplUnitTest) Time elapsed: 0 sec <<< ERROR!
java.lang.Exception: Unexpected exception, expected<org.springframework.security
.oauth2.provider.ClientAlreadyExistsException> but was<java.lang.NoSuchMethodErr
or>
at uk.co.jemos.podam.api.AbstractRandomDataProviderStrategy.addSpecific(
AbstractRandomDataProviderStrategy.java:505)
at com.xxxxx.api.services.CustomClientDetailsServiceImplUnitTest.t
estAddClientDetailsThatIfRecordExistShouldThrowException(CustomClientDetailsServ
iceImplUnitTest.java:184)
testUpdateClientDetailsThatItSavesOauthClientDetailsObject(com.xxxxx.api.s
ervices.CustomClientDetailsServiceImplUnitTest) Time elapsed: 0 sec <<< ERROR!
java.lang.NoSuchMethodError: java.util.Map.putIfAbsent(Ljava/lang/Object;Ljava/l
ang/Object;)Ljava/lang/Object;
at uk.co.jemos.podam.api.AbstractRandomDataProviderStrategy.addSpecific(
AbstractRandomDataProviderStrategy.java:505)
@
The specific test in question:
@ContextConfiguration(locations = {"classpath:"})
public class CustomClientDetailsServiceImplUnitTest {
CustomClientDetailsServiceImpl customClientDetailsServiceImpl = new CustomClientDetailsServiceImpl();
OauthClientDetailsRepository mockOauthClientDetailsRepository;
PasswordEncoder mockPasswordEncoder;
@Before
public void setUp() {
this.mockOauthClientDetailsRepository = Mockito.mock(OauthClientDetailsRepository.class);
this.mockPasswordEncoder = Mockito.mock(PasswordEncoder.class);
this.customClientDetailsServiceImpl.setRepository(this.mockOauthClientDetailsRepository);
this.customClientDetailsServiceImpl.setPasswordEncoder(this.mockPasswordEncoder);
}
@Test
public void testLoadClientByClientIdThatItFetchesClient() {
PodamFactory factory = new PodamFactoryImpl();
OauthClientDetails oauthClientDetails = factory.manufacturePojo(OauthClientDetails.class);
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(oauthClientDetails);
ClientDetails result = this.customClientDetailsServiceImpl.loadClientByClientId("");
Assert.assertNotNull(result);
}
@Test(expected = NoSuchClientException.class)
public void testLoadClientByClientIdThatIfNoClientExistShouldThrowError() {
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(null);
this.customClientDetailsServiceImpl.loadClientByClientId("");
}
@Test
public void testUpdateClientSecretTestThatClientSecretIsUpdated() {
PodamFactory factory = new PodamFactoryImpl();
OauthClientDetails oauthClientDetails = factory.manufacturePojo(OauthClientDetails.class);
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(oauthClientDetails);
Mockito.when(this.mockPasswordEncoder.encode(Mockito.anyString())).thenReturn("");
Mockito.when(this.mockOauthClientDetailsRepository.save(Mockito.any(OauthClientDetails.class))).thenReturn(null);
this.customClientDetailsServiceImpl.updateClientSecret("","");
Mockito.verify(this.mockOauthClientDetailsRepository, Mockito.times(1)).save(Mockito.any(OauthClientDetails.class));
Mockito.verify(this.mockPasswordEncoder, Mockito.times(1)).encode(Mockito.anyString());
}
@Test(expected = NoSuchClientException.class)
public void testUpdateClientSecretThrowsExceptionWhenClientDoesNotExist() {
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(null);
this.customClientDetailsServiceImpl.updateClientSecret("", "");
}
@Test
public void testRemoveClientDetailsThatItDeletesRecord() {
PodamFactory factory = new PodamFactoryImpl();
OauthClientDetails oauthClientDetails = factory.manufacturePojo(OauthClientDetails.class);
Mockito.doNothing().when(this.mockOauthClientDetailsRepository).delete(Mockito.any(OauthClientDetails.class));
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(oauthClientDetails);
this.customClientDetailsServiceImpl.removeClientDetails("");
Mockito.verify(this.mockOauthClientDetailsRepository, Mockito.times(1)).delete(Mockito.any(OauthClientDetails.class));
}
@Test(expected = NoSuchClientException.class)
public void testRemoveClientDetailsThatItThrowsErrorWhenClientDetailsNotFound() {
Mockito.doNothing().when(this.mockOauthClientDetailsRepository).delete(Mockito.any(OauthClientDetails.class));
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(null);
this.customClientDetailsServiceImpl.removeClientDetails("");
Mockito.verify(this.mockOauthClientDetailsRepository, Mockito.times(0)).delete(Mockito.any(OauthClientDetails.class));
}
@Test
public void testListClientDetailsThatItReturnsAListOfClientDetailsObjects()
{
PodamFactory factory = new PodamFactoryImpl();
List<OauthClientDetails> oauthClientDetails = new ArrayList<OauthClientDetails>();
oauthClientDetails.add(factory.manufacturePojo(OauthClientDetails.class));
oauthClientDetails.add(factory.manufacturePojo(OauthClientDetails.class));
Mockito.when(this.mockOauthClientDetailsRepository.findAll()).thenReturn(oauthClientDetails);
List<ClientDetails> results = this.customClientDetailsServiceImpl.listClientDetails();
Assert.assertEquals(results.size(), oauthClientDetails.size());
}
@Test
public void testListClientDetailsThatIfReturnsEmptyListMethodRetunsNull()
{
Mockito.when(this.mockOauthClientDetailsRepository.findAll()).thenReturn(null);
List<ClientDetails> results = this.customClientDetailsServiceImpl.listClientDetails();
Assert.assertTrue(results.size() == 0);
}
@Test
public void testAddClientDetailsThatItSavesOauthClientDetailsObject()
{
PodamFactory factory = new PodamFactoryImpl();
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(GrantedAuthority.class, SimpleGrantedAuthority.class);
BaseClientDetails baseClientDetails = factory.manufacturePojo(BaseClientDetails.class);
baseClientDetails.setAdditionalInformation(new HashMap<String, Object>(){{
put("test","test");
put("test1","test1");
}});
Mockito.when(this.mockOauthClientDetailsRepository.save(Mockito.any(OauthClientDetails.class))).thenReturn(null);
this.customClientDetailsServiceImpl.addClientDetails(baseClientDetails);
Mockito.verify(this.mockOauthClientDetailsRepository,Mockito.times(1)).save(Mockito.any(OauthClientDetails.class));
}
@Test(expected = ClientAlreadyExistsException.class)
public void testAddClientDetailsThatIfRecordExistShouldThrowException()
{
PodamFactory factory = new PodamFactoryImpl();
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(GrantedAuthority.class, SimpleGrantedAuthority.class);
BaseClientDetails baseClientDetails = factory.manufacturePojo(BaseClientDetails.class);
baseClientDetails.setAdditionalInformation(new HashMap<String, Object>() {{
put("test", "test");
put("test1", "test1");
}});
Mockito.when(this.mockOauthClientDetailsRepository.save(Mockito.any(OauthClientDetails.class))).thenThrow(new DataIntegrityViolationException(""));
this.customClientDetailsServiceImpl.addClientDetails(baseClientDetails);
}
@Test
public void testUpdateClientDetailsThatItSavesOauthClientDetailsObject()
{
PodamFactory factory = new PodamFactoryImpl();
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(GrantedAuthority.class, SimpleGrantedAuthority.class);
BaseClientDetails baseClientDetails = factory.manufacturePojo(BaseClientDetails.class);
baseClientDetails.setAdditionalInformation(new HashMap<String, Object>(){{
put("test","test");
put("test1","test1");
}});
OauthClientDetails oauthClientDetails = factory.manufacturePojo(OauthClientDetails.class);
Mockito.when(this.mockOauthClientDetailsRepository.findOne(Mockito.any(Specification.class))).thenReturn(oauthClientDetails);
Mockito.when(this.mockOauthClientDetailsRepository.save(Mockito.any(OauthClientDetails.class))).thenReturn(new OauthClientDetails());
this.customClientDetailsServiceImpl.updateClientDetails(baseClientDetails);
Mockito.verify(this.mockOauthClientDetailsRepository, Mockito.times(1)).save(Mockito.any(OauthClientDetails.class));
}
}
It would be nice to be able to have only the annotations on the production classpath, importing the actual implementation logic on the test classpath only.
There is an issue with generation String fields marked Size annotation with only min value parameter.
@Size(min = 1)
private String name;
In such case max value parameter is Integer.MAX_INT, so BeanValidationStrategy tries to create string with length [min, Integer.MAX_INT]. This action usually ends up with OOM exception.
Is it possible to limit max length of generated string by some reasonable constant (10 for example)?
Or maybe there is some other way to overcome this problem without modifying source code of domain objects (can't use PodamStringValue annotation or add max parameter)?
I have some changes to share back.
This includes a few small bug fixes, but more importantly (1) the processing of fields which do not have setters, (2) using the instantiated pojo when fetching instances of collections from a field, rather than instantiating a new object with a no-arg constructor or such, (3) some JUnit tests.
-John
Need a way to register a factory for Optional types, or more generally, a way to register a factory for any given type would be better than nothing. This is without having to modify the original class too.
When invoking PodamUtils.getClassInfo with a null argument for ClassAttributeApprover PODAM is throwing a NullPointerException.
Hey guys:
Love the plugin. I'm trying to fill data in this object https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java. However, as you can see there's a property called authorities
of type _GrantedAuthority_ (line 69). This type is an interface and whenever I try to create the object with factory.manufacturePojo
I get the issue that it's not able to instantiate an interface (which is understandable.). Is there a way to supply to _PodamFactory_ that whenever it encounters that interface, it should use a specific base class to instantiate?
Goals:
Please refer to coverage report. A number of paths haven't been tested
http://mtedone.github.io/podam/jacoco/uk.co.jemos.podam.common/BeanValidationStrategy.html
http://mtedone.github.io/podam/jacoco/uk.co.jemos.podam.common/MethodComparator.java.html#L24
Hi, thank you for your library, its so helpful in unit testing.
However, I noticed problem with using boolean fields:
I try to generate class using podamFactory.manufacturePojo(Test.class);
i have class:
public class Test{
private boolean visible;
public boolean setVisible(boolean visible){this.visible = visible;}
public boolean isVisible(){ return visible;}
}
There are also other fields, with other types, but boolean fields causes problem:
java.lang.NoSuchMethodException - no getter for field Visible.
I see framework is trying to use getVisible - but for booleans i use isFieldName
I could not find similar issue, if it is not valid, please let me know
In order to create strategies without annotate our POJOs with Podam annotations, it would be interesting to have access to class type in AttributeMetaData.
Today, AttributeMetaData contains only:
import java.util.List;
import uk.co.jemos.podam.api.PodamFactory;
import uk.co.jemos.podam.api.PodamFactoryImpl;
public class PodamTest {
public class Pojo {
private List<? extends Object> objs;
public List<? extends Object> getObjs() {
return objs;
}
public void setObjs(List<? extends Object> objs) {
this.objs = objs;
}
@Override
public String toString() {
return "{objs: '" + objs + "'}";
}
}
public static void main(String[] args) {
PodamFactory factory = new PodamFactoryImpl();
Pojo pojo = factory.manufacturePojo(Pojo.class);
System.out.println(pojo);
}
}
This small test results in the following exception:
[java] Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.WildcardTypeImpl cannot be cast to java.lang.Class
[java] at uk.co.jemos.podam.api.PodamFactoryImpl.resolveCollectionValueWhenCollectionIsPojoAttribute(PodamFactoryImpl.java:1969)
[java] at uk.co.jemos.podam.api.PodamFactoryImpl.manufactureAttributeValue(PodamFactoryImpl.java:1646)
[java] at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1485)
[java] at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:109)
[java] at PodamTest.main(PodamTest.java:27)
podam-5.3.1.RELEASE
/uk/co/jemos/podam/api/PodamFactoryImpl.java:1839
Integer depth = pojos.get(realAttributeType);
if (depth == null) {
depth = -1;
}
if (depth <= strategy.getMaxDepth(pojo.getClass())) {
pojos.put(realAttributeType, depth + 1);, //<-- increment depth
attributeValue = this.manufacturePojoInternal(
realAttributeType, attributeMetadata, pojos, genericTypeArgsAll);
pojos.put(realAttributeType, depth);//<-- put -1 again
}
For example
public class A {
private List<C> listOfC;
public List<C> getListOfC() {
return listOfC;
}
public void setListOfC(List<C> listOfC) {
this.listOfC = listOfC;
}
}
public class B {
List<A> listOfC;
public List<A> getListOfC() {
return listOfC;
}
public void setListOfC(List<A> listOfC) {
this.listOfC = listOfC;
}
}
public class C {
List<B> listOfB;
public List<B> getListOfB() {
return listOfB;
}
public void setListOfB(List<B> listOfB) {
this.listOfB = listOfB;
}
}
next snippet will cause infinity loop(!= StackOverflowError)
@Test
public void testLoop() {
A a =new PodamFactoryImpl().manufacturePojo(A.class);
}
I'm trying to use PODAM in a Play! framework (http://www.playframework.org) application.
I know that Play! internal mecanism is none of your business, but you might shed some light on the issue I face.
A simple test with two POJOs works fine in a regular Maven java project : cf. https://github.com/Fluor/podamtest.
To reproduce :
The test with same POJOs classes in a Play! application raises ClassNotFoundException : cf. https://github.com/Fluor/podamplaytest
To reproduce and see ClassNotFoundException :
I know that Play! use dynamic bytecode generation, which might be the root of this issue.
Have you ever used Play! framework and faced this issue?
Thanks in advance.
Feel free to close this issue as it might not be a PODAM issue.
It provides benefits to have different data in your POJO even at cost of performance.
Calling AbstractRandomDataProviderStrategy.addAttributeStrategy() and AbstractRandomDataProviderStrategy.addSpecific() has no effect if there is already mapping or attribute strategy present.
Despite JavaDocs specifies correct behavior:
http://mtedone.github.io/podam/apidocs/uk/co/jemos/podam/api/AbstractRandomDataProviderStrategy.html#addSpecific-java.lang.Class-java.lang.Class-
Both methods define unused variable aClass and attributeStrategyClass
Class<?> aClass = specificTypes.putIfAbsent(abstractClass, specificClass);
if (null == aClass) {
aClass = specificClass;
}
Class<AttributeStrategy<?>> attributeStrategyClass = attributeStrategies.putIfAbsent(annotationClass, strategyClass);
if (null == attributeStrategyClass) {
attributeStrategyClass = strategyClass;
}
Thank you for Podam. I use it in production to generate samples requests for web service APIs. These POJOs often contain XmlGregorianCalendar
properties. Here is a patch for PodamFactoryImpl
to return values when instantiation requires the use of the XML Datatype factory.
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
// A factory to create objects that map XML to/from Java.
private static DatatypeFactory xmlDatatypeFactory;
public static DatatypeFactory getXmlDatatypeFactory()
{
if ( xmlDatatypeFactory == null )
{
try
{
xmlDatatypeFactory = DatatypeFactory.newInstance();
}
catch (DatatypeConfigurationException e)
{
throw new RuntimeException("Podam factory cannot create XML factory.", e);
}
}
return xmlDatatypeFactory;
}
createNewInstanceForClassWithoutConstructors(...)
method, within the test for 'no constructors' and after the loop to find a 'getInstance()' method, add this code...// Did we find a getInstance() method to create the return value?
if ( retValue == null )
{
// No return value, so far.
// Can we use an XML DatatypeFactory to create an instance?
if ( XMLGregorianCalendar.class.isAssignableFrom(clazz) )
{
retValue = getXmlDatatypeFactory().newXMLGregorianCalendar(new GregorianCalendar());
}
else if ( Duration.class.isAssignableFrom(clazz) )
{
List<Annotation> annotations = new ArrayList<Annotation>();
getLongValueWithinRange(annotations, null);
retValue = getXmlDatatypeFactory().newDuration(0L);
}
}
And a suggestion: Change the log.info(...)
in PodamFactoryImpl
to log.debug(...)
. This would allow my SysAdmin to set the log level to INFO instead of WARN without a flood of details from this class, IMHO.
Hi,
I tried to manufacture a DataHandler object(http://docs.oracle.com/javase/7/docs/api/javax/activation/DataHandler.html) but i incurred in infinite loop.
Infact if i tried to execute this code, program never stops:
public static void main( String[] args ) throws MalformedURLException
{
BasicConfigurator.configure();
PodamFactory factory = new PodamFactoryImpl();
DataHandler myPojo = factory.manufacturePojo(DataHandler.class);
System.out.println(myPojo.toString());
}
These are just several of infinite log lines for my little program :P
1087 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - For class: java.net.URL PODAM could not possibly create a value. This attribute will be returned as null.
1087 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - Couldn't create attribute with constructor: public java.net.URLStreamHandler(). Will check if other constructors are available
1087 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - For class: java.net.URLStreamHandler PODAM could not possibly create a value. This attribute will be returned as null.
1088 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - Couldn't create attribute with constructor: public java.net.URL(java.net.URL,java.lang.String,java.net.URLStreamHandler) throws java.net.MalformedURLException. Will check if other constructors are available
1089 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - Couldn't create attribute with constructor: public java.net.URL(java.lang.String,java.lang.String,java.lang.String) throws java.net.MalformedURLException. Will check if other constructors are available
1089 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - Couldn't create attribute with constructor: public java.net.URL(java.lang.String,java.lang.String,int,java.lang.String) throws java.net.MalformedURLException. Will check if other constructors are available
1090 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - Couldn't create attribute with constructor: public java.net.URLStreamHandler(). Will check if other constructors are available
1090 [main] WARN uk.co.jemos.podam.api.PodamFactoryImpl - For class: java.net.URLStreamHandler PODAM could not possibly create a value. This attribute will be returned as null.
Hello! I'm using 5.5.1.RELEASE Podam version.
I'm tryng to do this:
RandomDataProviderStrategy strategy = new RandomDataProviderStrategyImpl();
strategy.addOrReplaceSpecific(XMLGregorianCalendar.class, XMLGregorianCalendarImpl.class);
PodamFactory factory = new PodamFactoryImpl(strategy);
XMLGregorianCalendar pojo = factory.manufacturePojo(XMLGregorianCalendar.class);
where XMLGregorianCalendarImpl is com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.
My code throws an Exception:
Exception in thread "main" uk.co.jemos.podam.exceptions.PodamMockeryException
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:182)
at it.sogei.podam.App.main(App.java:35)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at uk.co.jemos.podam.api.PodamFactoryImpl.populatePojoInternal(PodamFactoryImpl.java:1407)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1249)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1234)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:175)
... 1 more
Caused by: java.lang.IllegalArgumentException: Valore -247.795.888 non valido per il campo Day.
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.invalidFieldValue(XMLGregorianCalendarImpl.java:1294)
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.setDay(XMLGregorianCalendarImpl.java:1250)
... 9 more
How can i fix this?
Thanks in advance. Best regards,
Alessandro.
Just tried getting Podam to generate LocalDateTime.java objects (new Java 8) and I'm having some problems. Tried using an ExternalFactory without any luck (seeing strange runtime issues). Only thing that works right now is @PodamStrategyValue.
With the version 5.5.1.RELEASE when you use log4 1.2.17 we have a problem.
The tests read log4j2.xml from podam jar and not use 1.2.17 configuration.
We try exclude log jars from podam dependency but the tests say "not found LogManager" from org.apache.logging.log4j
https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/LogManager.html
We move to 5.4.1.RELEASE and this version is Ok
Multiple instances of Podam must be able to run within the same JVM without affecting each other's results.
Podam unit tests behave differently in JDK6 and JDK7. In JDK6 for BigInteger creation
BigInteger(int numBits, Random rnd)
is picked up, however, in JDK7
BigInteger(int bitLength, int certainty, Random rnd)
is found first. The latter is really heavy call causing unit tests to do a heavy work for many minutes.
Trying to deal with this problem, I introduced a sorting for POJO constructors, in such a way, that constructors with Podam annotations will be tried first and then, if not successful, constructors with less parameters will be used. The rationale behind the change is so that in general mocking less parameters should be easier
daivanov@260dc62
However, I do understand that constructors with less parameters do not guarantee success, as meaning of parameters is not known to Podam.
Another point is that sorting will make Podam behave more predictable with different JDK versions.
While working on my fork, #24, I found that Pdm4PojoUnitTest fail on jdk7. You can see the build results here:
https://travis-ci.org/astubbs/podam/builds/14044898
Where it passes on jdk6 but fails on jdk7.
Classes generated by the JAXB compiler, xjc, produces properties that may include a JAXBElement<T>
wrapper. This wrapper is used to encapsulate information related to the XML schema such as the QName
(namespace + element name), etc. The wrapper stores the actual property value in its own getValue()
/ setValue(...)
property. Here is a patch for the manufactureAttributeValue
method of the PodamFactoryImpl
class to create the wrapper and generate a mock of the actual type. It is located just ahead of the exitsing test for "java"
and "javax"
classes.
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
...
if ( realAttributeType.getName().startsWith("javax.xml.bind.JAXBElement"))
{
@SuppressWarnings("unchecked")
Class<Object> declaredType = (Class<Object>) genericTypeArgs[0];
String namepaceURI = pojoClass.getPackage().getName();
QName name = new QName(namepaceURI, attributeName);
Object value = manufactureAttributeValue(pojoClass, pojos, declaredType,
annotations, attributeName, new Type[0]);
attributeValue = new JAXBElement<Object>(name, declaredType, value);
}
else if (realAttributeType.getName().startsWith("java.")
|| realAttributeType.getName().startsWith("javax.")) {
...
Trying to create a POJO of a Spring Oauth Security Object shows this error:
08:37:58.972 [main] DEBUG u.c.jemos.podam.api.PodamFactoryImpl - We couldn't create an instance for pojo: class org.springframework.security.oauth2.provider.OAuth2Authentication with constructor: public org.springframework.security.oauth2.provider.OAuth2Authentication(org.springframework.security.o auth2.provider.OAuth2Request,org.springframework.security.core.Authentication). Will try with another one.
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
at uk.co.jemos.podam.api.PodamFactoryImpl.populatePojoInternal(PodamFactoryImpl.java:1397) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1239) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1197) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufactureAttributeValue(PodamFactoryImpl.java:1635) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufactureParameterValue(PodamFactoryImpl.java:30 59) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.getParameterValuesForConstructor(PodamFactoryImpl.java:2829) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.instantiatePojo(PodamFactoryImpl.java:1092) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1212) [podam-5.4.1.RELEASE.jar:na]
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:170) [podam-5.4.1.RELEASE.jar:na]
at com.cointraders.api.services.CustomTokenStoreServiceUnitTest.testReadAuthenticationThatItReturnsOAuth2Authentication(CustomTokenStoreServiceUnitTest.java:73) [test-classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
at org.junit.runner.JUnitCore.run(JUnitCore.java:160) [junit-4.11.jar:na]
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) [junit-rt.jar:na]
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) [junit-rt.jar:na]
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) [junit-rt.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~ [na:1.8.0_40]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) [idea_rt.jar:na]
Caused by: java.lang.IllegalArgumentException: Once created you cannot set this token to authenticated. Create a new instance using the constructor which takes a GrantedAuthority list will mark this as authenticated.
at org.springframework.security.authentication.UsernamePasswordAuthenticationToken.setAuthenticated(UsernamePasswordAuthenticationToken.java:87) ~[spring-security-core-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 41 common frames omitted
08:37:59.162 [main] DEBUG u.c.jemos.podam.api.PodamFactoryImpl - For class class org.springframework.security.oauth2.provider.OAuth2Authentication PODAM could not possibly create a value. Will try other means.
08:37:59.165 [main] WARN u.c.jemos.podam.api.PodamFactoryImpl - Failed to manufacture class org.springframework.security.oauth2.provider.OAuth2Authentication. Resorting to uk.co.jemos.podam.api.NullExternalFactory external factory
08:37:59.167 [main] WARN u.c.j.podam.api.NullExternalFactory - Cannot instantiate class org.springframework.security.oauth2.provider.OAuth2Authentication with arguments []. Returning null.
The Spring Oauth2 library version I'm using is 2.0.7.RELEASE
My actual test:
@Test
public void testReadAuthenticationThatItReturnsOAuth2Authentication()
{
PodamFactory factory = new PodamFactoryImpl();
DefaultOAuth2AccessToken oAuth2AccessToken = factory.manufacturePojo(DefaultOAuth2AccessToken.class);
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(OAuth2RefreshToken.class, DefaultOAuth2RefreshToken.class);
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(Authentication.class, UsernamePasswordAuthenticationToken.class);
((RandomDataProviderStrategy)factory.getStrategy()).addSpecific(GrantedAuthority.class,SimpleGrantedAuthority.class);
OauthAccessToken oauthAccessToken = factory.manufacturePojo((OauthAccessToken.class));
OAuth2Authentication oAuth2Authentication = factory.manufacturePojo(OAuth2Authentication.class);
byte[] byteOauth2Authentication = SerializationUtils.serialize(oAuth2Authentication);
oauthAccessToken.setAuthentication(byteOauth2Authentication);
Mockito.when(this.mockOauthAccessTokenRepository.findOne(Mockito.any(Specification.class))).thenReturn(oauthAccessToken);
OAuth2Authentication result = this.customTokenStoreServiceImpl.readAuthentication(oAuth2AccessToken);
Assert.assertNotNull(result);
}
On project website http://www.jemos.co.uk/projects/podam/, menu "Technical Reference/A Walk-through example" links to http://home.btconnect.com/jemos//projects/podam/walk-through-example.html wich gaves "404 Not found".
Example code reproducing the issue:
public interface ObjectExt {
public T getValue();
public void setValue(T value);
}
public class FloatExt implements ObjectExt {
private Float value;
@Override
public Float getValue() {
return value;
}
@Override
public void setValue(Float value) {
this.value = value;
}
}
public class Main {
public static void main(String[] args) {
PodamFactory podamFactory = new PodamFactoryImpl();
FloatExt floatExt = podamFactory.manufacturePojo(FloatExt.class);
}
}
[main] INFO uk.co.jemos.podam.api.PodamFactoryImpl - We could create an instance with constructor: public FloatExt()
[main] INFO uk.co.jemos.podam.api.PodamFactoryImpl - For class: java.lang.Object a valid constructor: public java.lang.Object() was found. PODAM will use it to create an instance.
Exception in thread "main" uk.co.jemos.podam.exceptions.PodamMockeryException:
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:153)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:135)
at Main.main(Main.java:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojoInternal(PodamFactoryImpl.java:1602)
at uk.co.jemos.podam.api.PodamFactoryImpl.manufacturePojo(PodamFactoryImpl.java:146)
... 7 more
Caused by: java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.Float
at FloatExt.setValue(FloatExt.java:2)
... 13 more
With Jackson, it is possible to configure it to only serialize fields (or only getters/setters), see this SO question for example: http://stackoverflow.com/questions/7105745/how-to-specify-jackson-to-only-use-fields-preferably-globally
This does not seem to be possible with the current version of PODAM. Having the ability to specify exclusions rules would be really nice and would allow PODAM to be used with a much larger classes of objects than just basic DTOs/beans/dumb storage classes.
I think this will also solve #80.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.