Testing abstract class constructor with JUnit - junit

Is there a simple way to test the following constructor in abstract class Woning with JUnit tests:
public abstract class Woning {
private int kamers;
private int vraagPrijs;
private Adres adres;
private boolean statusWoning;
public Woning(Adres adres, int kamers, int vraagPrijs, boolean statusWoning) {
this.adres = adres;
this.kamers = kamers;
this.vraagPrijs = vraagPrijs;
this.statusWoning = statusWoning;
}

I would create a class which would extend it for the unit test just like we sometimes create mock classes, and create a constructor that calls the super constructor.

Related

JUnit 5.6.0 with static autoincrement field initializes it twice

I have a strange issue with JUnit 5.6.0 that I don't recall it was there before.
class Student {
private static int autoInc = 0;
private int regNum = 0;
public Student(...) {
regNum = autoInc++;
}
public int getRegNum() { return regNum; }
//...
}
and the unit test
public class StudentTest {
private final Student instance = new Student(...);
#BeforeEach
public void setUp() {}
#AfterEach
public void tearDown() {}
#DisplayName("getRegNum")
#Test
public void testGetRegNum() {
assertEquals(1, instance.getRegNum());
}
}
When I execute it, instead of having the test pass, it fails because the instance's regNum field has value 2 instead of 1.
After debugging, I realized that a NativeConstructorAccessorImpl is being called twice who creates 2 instances of Student which explains why the static fields has been called two times.
Why is this and how can I avoid it? This is something internal to the JUnit framework but it affects my unit test case. Of course I don't want to pollute my class with a setter or a public static field.

Blaze Persistence EntityView inheritance mapping

I'm currently using Quarkus combined with Blaze Persistence for my microservice. I have the following entity model:
#Entity
public class Content extends BaseEntity {
private boolean deleted;
private boolean published;
}
#Entity
public class WebContent extends Content {
private String webpage;
}
I've mapped the entities to the following EntityViews:
#EntityView(Content.class)
#EntityViewInheritance
#CreatableEntityView
#UpdatableEntityView
public interface ContentUpdateView {
#IdMapping
Long getId();
boolean isPublished();
void setPublished(boolean published);
}
#EntityView(WebContent.class)
#CreatableEntityView
#UpdatableEntityView
public interface WebContentUpdateView extends ContentUpdateView {
String getWebpage();
void setWebpage(String webpage);
}
I have the following method in my ContentsResource:
#POST
public ContentUpdateView save(ContentUpdateView content) {
return contentsService.save(content);
}
When I invoke the post operation I only get the base ContentUpdateView and not the WebContentUpdateView. Is there any configuration to do? (with Jackson I use #JsonTypeInfo and #JsonSubType annotation on the entities to accomplish this).
Thanks
euks
I got it working using Jackson annotation. Here's the base class:
#EntityView(Content.class)
#EntityViewInheritance
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "type")
#JsonSubTypes({
#JsonSubTypes.Type(value = DescriptiveContentView.class, name = "descriptive"),
#JsonSubTypes.Type(value = MediaContentView.class, name = "media"),
#JsonSubTypes.Type(value = WebContentView.class, name = "web")
})
#JsonTypeName("content")
public abstract class ContentView {
#IdMapping
public abstract Long getId();
public abstract boolean isPublished();
}
And here's a subclass:
#EntityView(DescriptiveContent.class)
#JsonTypeName("descriptive")
public abstract class DescriptiveContentView extends ContentView {
public abstract Set<LocalizedParagraphView> getLocalizedParagraphs();
}
I'm using abstract classes for other purposes, but it also works with interfaces.

SpringData JPA - Provided id of the wrong type for class . Expected: class java.lang.Integer, got class java.lang.Long

i'm facing this issue while using Spring JPA and trying to retrieve a List of objects.
This is the class i'm trying to retrieve
#Entity
#Table(name="OBJECTSTERMIC")
public class TermicObject {
#Id
#Column(name="TERMICID")
private long termicId;
#MapsId
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="OBJECTID",columnDefinition="INTEGER")
private Object object;
#Column(name="CONTECA_RIF")
private int contecaRif;
#Column(name="CONTECA_VAL")
private int contecaVal;
#Column(name="TYPE")
private String type;
//getters and setters
The Object class has the primary key on MySQL stored as an Integer, indeed this is Object
#Entity
public class Object {
#Column(name="OBJECTID")
#Id
#JsonProperty("OBJECTID")
private int objectId;
....
So, nowhere is set a Long...
Now, i simply call in a service class
#Override
public List<TermicObject> findAll() {
return repository.findAll();
}
and got this exception
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TypeMismatchException: Provided id of the wrong type for class it.besmart.db_eipo.persistence.model.Object. Expected: class java.lang.Integer, got class java.lang.Long; nested exception is java.lang.IllegalArgumentException: org.hibernate.TypeMismatchException: Provided id of the wrong type for class it.besmart.db_eipo.persistence.model.Object. Expected: class java.lang.Integer, got class java.lang.Long
Where is set that Object Id should be Long?
Have a look at definition of your repository. Does it have right generic type? do you have Integer as second parameter? IMHO this can be root cause. See proposed correct version:
#RepositoryRestResource
public interface TermicObjectRepository extends JpaRepository<TermicObject, Integer> {
public Optional<TermicObject> findById(Integer id);
public List<TermicObject> findAll()
}
As per #Lubo's answer, in my case I was having compatibility issues between String and Long types and as my model required a Long autogenerated id I had to change the repository from
public interface ProductRepository extends JpaRepository<Product, String> {
}
to
public interface ProductRepository extends JpaRepository<Product, Long> {
}
And my controller from
#RequestMapping(path = "/products/delete/{id}", method = RequestMethod.DELETE)
public void deleteProduct(#PathVariable(name = "id") String id) {
productRepository.deleteById(id);
}
to
#RequestMapping(path = "/products/delete/{id}", method = RequestMethod.DELETE)
public void deleteProduct(#PathVariable(name = "id") Long id) {
productRepository.deleteById(id);
}
You have to define your id as a Long datatype.
#Id
#Column(name="TERMICID")
private Long termicId;
also make a change in your repository interface:
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Got this because
public class MyEntity {
#Id()
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private int id; // <-------- int
...
public long getId() { return id; } // <-------- long
}
Not completely sure, but I think this mapping
#Id
#Column(name="TERMICID")
private long termicId;
#MapsId
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="OBJECTID",columnDefinition="INTEGER")
private Object object;
Makes the id of the Object match the value of termicId which is a long.
use
Long.valueOf(intValue)
to cast int to Long type because you define type Long to #Id

jackson array deserilization to properties of singe object java

I have a the class structure as below:
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
#JsonSubTypes({
#JsonSubTypes.Type(name = "testA", value = TestA.class),
#JsonSubTypes.Type(name = "testB", value = TestB.class),
#JsonSubTypes.Type(name = "testC", value = TestC.class)
})
public abstract class Test {
}
public class TestA extends Test {
private String firstName;
private String secondName;
private String surName;
}
public class TestB extends Test {
private String adressLine1;
private String adressLine2;
private String adressLine3;
}
public class TestC extends Test {
private String hobby1;
private String hobby2;
private String hobby3;
}
The above classes are serialized into array of json elements, but when I de-serialise them back, i want the structure as below:
public class FlatStructure {
private TestA testA;
private TestB testB;
private TestC testC;
public void setTestA(TestA testA){
this.testA = testA;
}
public TestA getTestA(){
return testA;
}
.....getter and setter for testB and testC...
}
is it possible to convert the array of elements of type testA, testB and testC to properties of FlatStructure class?
You can add a constructor with the annotation #JsonCreator
, in each class Test
and another one in you flat Structure Class,
after that you use an ObjectMapper to create your class FlatStructure
I would recommend to use the annotaions #JsonProperty also on your constructor
check this link
http://buraktas.com/convert-objects-to-from-json-by-jackson-example/
i think that
public class TestA extends Test {
.....
#JsonCreator
public TestA(#JsonProperty("firstName") String name,
#JsonProperty("secondName") String secondeName,
#JsonProperty("surName") String surName){
this.firstName=name;
this.secondeName=secondeName;
this.surName=surName;
}
... getter, setter .....
}
public class TestB extends Test {
.....
#JsonCreator
public TestB(#JsonProperty("adressLine1") String adressLine1,
#JsonProperty("adressLine2") String adressLine2,
#JsonProperty("adressLine3") String adressLine3){
this.adressLine1=adressLine1;
this.adressLine2=adressLine2;
this.adressLine3=adressLine3;
}
... getter, setter .....
}
public class TestC extends Test {
.....
#JsonCreator
public TestC(#JsonProperty("hobby1") String hobby1,
#JsonProperty("hobby2") String hobby2,
#JsonProperty("hobby3") String hobby3){
this.hobby1=hobby1;
this.hobby2=hobby2;
this.hobby3=hobby3;
}
... getter, setter .....
}
public class FlatStructure{
private TestA testA;
private TestB testB;
private TestC testC;
#JsonCreator
public FlatStructure(#JsonProperty("testA") testA testa,
#JsonProperty("testB") testB testb,
#JsonProperty("testC") testC testc){
this.testA =testa;
this.testB =testb;
this.testC =testc;
}
... getter, setter .....
}
Should work properly with a mapper
Edit:
Custom JSON Deserialization with Jackson
http://www.baeldung.com/jackson-deserialization

GWT Autobean without setter method

I am using Autobean framework to encode/decode JSON in my GWT application. It works in cases with the interfaces having getters and setters. But is there any way to do it some other way to do this without specifying a setThisCollectionProperty instead using an addToThisCollectionProperty method?
For example, I have an interface IPerson like this:
public interface IPerson {
public String getName();
public void setName(String name);
public int getAge();
public void setAge(int age);
public List<String> getIds();
public void addId(String id);
}
BeanFactory is like this:
public interface BeanFactory extends AutoBeanFactory {
public AutoBean<IPerson> person();
public AutoBean<IPerson> person(IPerson person);
}
and in Person class which implements IPerson,
public class Person implements IPerson {
private String name;
private List<String> ids;
...
public List<String> getIds() {
return ids;
}
public void addId(String id) {
...
ids.add(id);
}
}
It works if the addId(String id) is replaced with setIds(List<String> ids).
Otherwise the following error is shown:
The com.mycompany.jsonsample.beans.IPerson parameterization is not simple, but the person method does not provide a delegate
Is it possible to encode/decode without a set method?
AutoBean manages all getters and setters, and only getters and setters. For any other method, you have to use a category.
Using a category, you could thus implement addId(…) as getIds().add(…), or possibly directly call addIds on the underlying object if the AutoBean is a wrapper.