{"id":18255449,"url":"https://github.com/roroche/javaobjectsonsteroids","last_synced_at":"2025-04-08T21:51:40.089Z","repository":{"id":217038135,"uuid":"96436772","full_name":"RoRoche/JavaObjectsOnSteroids","owner":"RoRoche","description":"Example with useful libraries to speed up Java objects writing and testing.","archived":false,"fork":false,"pushed_at":"2020-04-26T16:50:19.000Z","size":417,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-14T17:22:52.111Z","etag":null,"topics":["assertj","assertj-assertions","autovalue","equals","hashcode","pojo","pojo-tester","pojo-testing","pojomatic","tostring","tostring-utilities"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RoRoche.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-07-06T14:03:35.000Z","updated_at":"2024-03-11T17:17:24.000Z","dependencies_parsed_at":"2024-01-14T08:05:13.631Z","dependency_job_id":null,"html_url":"https://github.com/RoRoche/JavaObjectsOnSteroids","commit_stats":null,"previous_names":["roroche/javaobjectsonsteroids"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoRoche%2FJavaObjectsOnSteroids","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoRoche%2FJavaObjectsOnSteroids/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoRoche%2FJavaObjectsOnSteroids/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoRoche%2FJavaObjectsOnSteroids/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RoRoche","download_url":"https://codeload.github.com/RoRoche/JavaObjectsOnSteroids/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247934802,"owners_count":21020724,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assertj","assertj-assertions","autovalue","equals","hashcode","pojo","pojo-tester","pojo-testing","pojomatic","tostring","tostring-utilities"],"created_at":"2024-11-05T10:16:27.399Z","updated_at":"2025-04-08T21:51:40.064Z","avatar_url":"https://github.com/RoRoche.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n$theme: gaia\ntemplate: gaia\n$size: 16:9\n--\u003e\n\nJava objects on steroids\n===\n\n# ![](assets/logo/res/mipmap-xxxhdpi/logo.png)\n\n###### by [Romain Rochegude](https://github.com/RoRoche)\n\n---\n\u003c!-- page_number: true --\u003e\n\n# Introduction\n\n* Many ways to see \"objects\": POJO, bean\n* Many concepts: encapsulation, inheritance, polymorphism, immutability\n* [Who Is an Object?](http://www.yegor256.com/2016/07/14/who-is-object.html)\n* [Seven Virtues of a Good Object](http://www.yegor256.com/2014/11/20/seven-virtues-of-good-object.html)\n\n---\n\n# ==1.== Write simple immutable object\n\n```java\npublic final class User {\n\n    private final int id;\n    private final String login;\n    private final String avatarUrl;\n\n    public User(\n            final int pId, \n            final String pLogin, \n            final String pAvatarUrl) {\n        id = pId;\n        login = pLogin;\n        avatarUrl = pAvatarUrl;\n    }\n    \n}\n```\n\n---\n\n# ==2.== Improve pojo methods testing with [pojo-tester](http://www.pojo.pl/)\n\n## \u003chttp://www.pojo.pl/\u003e\n\n---\n\n## Gradle installation:\n\n```groovy\nrepositories {\n    jcenter()\n}\n\ndependencies {\n    testCompile 'pl.pojo:pojo-tester:${latest-version}'\n}\n```\n\n---\n\n## Write unit test:\n\n```java\nimport pl.pojo.tester.api.assertion.Method;\nimport static pl.pojo.tester.api.assertion.Assertions.assertPojoMethodsFor;\n\npublic class UserTest {\n    @Test\n    public void Should_Pass_All_User_Tests() {\n        assertPojoMethodsFor(\n                User.class\n        ).testing(\n                Method.EQUALS,\n                Method.HASH_CODE,\n                // Method.SETTER,\n                // Method.GETTER,\n                // Method.TO_STRING,\n                Method.CONSTRUCTOR\n        ).areWellImplemented();\n    }\n}\n```\n\n---\n\n## Why...\n\n* ...no getters/setters testing?\n    * Because [getters/setters are evil](http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html)\n* ...no `toString`?\n    * Because it expects a specific format that is not extensible\n\n---\n\n## The result is:\n\n```java\nClass fr.guddy.joos.domain.User has bad 'hashCode' method implementation.\nThe hashCode method should return same hash code for equal objects.\nCurrent implementation returns different values.\nObject:\nfr.guddy.joos.domain.User@7946e1f4\nand\nfr.guddy.joos.domain.User@5cc7c2a6\nhave two different hash codes:\n2034688500\nand\n1556595366\n```\n\n---\n\n# ==3.== Improve pojo methods writing with [pojomatic](http://www.pojomatic.org/)\n\n## \u003chttp://www.pojomatic.org/\u003e\n\n---\n\n## Why pojomatic instead of Commons Lang, Guava or Lombok?\n\n* Because pojomatic is only focused on the `equals(Object)`, `hashCode()` and `toString()` methods\n* Because Commons Lang are verbose\n* Because Guava has many other features\n* Because Lombok needs an extra plugin and \n\n---\n\n## Gradle installation:\n\n```java\ncompile 'org.pojomatic:pojomatic:2.0.1'\n```\n\n---\n\n## Configure object:\n\n```java\nimport org.pojomatic.Pojomatic;\nimport org.pojomatic.annotations.Property;\n\npublic final class User {\n    @Property\n    private final int id;\n    // ...\n\n    @Override\n    public boolean equals(final Object pObj) {\n        return Pojomatic.equals(this, pObj);\n    }\n\n    @Override\n    public int hashCode() {\n        return Pojomatic.hashCode(this);\n    }\n}\n```\n\n---\n\n# ==4.== Improve immutable writing with [auto-value](https://github.com/google/auto/tree/master/value)\n\n## \u003chttps://github.com/google/auto/tree/master/value\u003e\n\n---\n\n## Gradle installation:\n\n```groovy\ncompile 'com.google.auto.value:auto-value:1.2'\nannotationProcessor 'com.google.auto.value:auto-value:1.2'\n```\n\n---\n\n## Configure object:\n\n```java\nimport com.google.auto.value.AutoValue;\n\n@AutoValue\npublic abstract class Repo {\n    public abstract int id();\n    public abstract String name();\n    public abstract String description();\n    public abstract String url();\n\n    public static Repo create(\n            final int pId, \n            final String pName, \n            final String pDescription, \n            final String pUrl) {\n            \n        return new AutoValue_Repo(pId, pName, pDescription, pUrl);\n    }\n}\n```\n\n---\n\n# ==5.== Improve object testing with [AssertJ Assertions Generator](http://joel-costigliola.github.io/assertj/assertj-assertions-generator.html)\n\n## \u003chttp://joel-costigliola.github.io/assertj/assertj-assertions-generator.html\u003e\n\n---\n\n## Why? Refer to [Single Statement Unit Tests](http://www.yegor256.com/2017/05/17/single-statement-unit-tests.html), for the following benefits:\n\n* Reusability\n* Brevity\n* Readability\n* Immutability\n* Fluent test result\n\n---\n\n## Gradle installation:\n\n### AssertJ dependency:\n\n```\ntestCompile 'org.assertj:assertj-core:3.8.0'\n```\n\n### assertjGen plugin installation:\n\n```groovy\nbuildscript {\n    repositories {\n        maven { url \"https://plugins.gradle.org/m2/\" }\n    }\n    dependencies {\n        classpath \"gradle.plugin.com.github.opengl-8080:\n          assertjGen-gradle-plugin:1.1.3\"\n    }\n}\n\napply plugin: \"com.github.opengl-BOBO.assertjGen\"\n```\n\n---\n\n### assertjGen plugin configuration:\n\n```groovy\nassertjGen {\n    classOrPackageNames = ['fr.guddy.joos.domain']\n    outputDir = 'src/test/java'\n    cleanOnlyFiles = true\n    assertjGenerator = 'org.assertj:assertj-assertions-generator:2.0.0'\n}\n```\n\n---\n\n## Run the `assertjGen` Gradle task to generate assertion classes\n\n## Write unit test:\n\n```java\nimport static fr.guddy.joos.domain.UserAssert.assertThat;\n\npublic class UserTest {\n    @Test\n    public void Should_Have_Matching_Id() {\n        assertThat(\n                new User(12,\n                        \"Romain\",\n                        \"https://...\")\n        ).hasId(13);\n    }\n}\n```\n\n---\n\n## The result is:\n\n```java\njava.lang.AssertionError: \nExpecting id of:\n  \u003cUser{id: {12}, login: {Romain}, avatarUrl: {https://...}}\u003e\nto be:\n  \u003c13\u003e\nbut was:\n  \u003c12\u003e\n```\n\n---\n\n# Conclusion\n\n* Focus on the objects\n* Less boilerplate code\n* On the way to DDD\n* On the way to hexagonal architecture\n\n* \u003chttps://github.com/RoRoche/JavaObjectsOnSteroids\u003e\n\n---\n\n# Bibliography\n\n* \u003chttp://www.yegor256.com/2014/11/20/seven-virtues-of-good-object.html\u003e\n* \u003chttp://www.yegor256.com/2016/07/14/who-is-object.html\u003e\n* \u003chttp://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html\u003e\n* \u003chttp://www.yegor256.com/2017/05/17/single-statement-unit-tests.html\u003e\n* \u003chttp://thierry-leriche-dessirier.developpez.com/tutoriels/java/simplifier-code-guava-lombok/\u003e\n\n---\n\n# Logo credits\n\nBusiness graphic by \u003ca href=\"http://www.flaticon.com/authors/freepik\"\u003efreepik\u003c/a\u003e from \u003ca href=\"http://www.flaticon.com/\"\u003eFlaticon\u003c/a\u003e is licensed under \u003ca href=\"http://creativecommons.org/licenses/by/3.0/\" title=\"Creative Commons BY 3.0\"\u003eCC BY 3.0\u003c/a\u003e. Made with \u003ca href=\"http://logomakr.com\" title=\"Logo Maker\"\u003eLogo Maker\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froroche%2Fjavaobjectsonsteroids","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froroche%2Fjavaobjectsonsteroids","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froroche%2Fjavaobjectsonsteroids/lists"}