{"id":37022818,"url":"https://github.com/stasha/testosterone","last_synced_at":"2026-01-14T02:43:47.999Z","repository":{"id":37280962,"uuid":"153834811","full_name":"stasha/testosterone","owner":"stasha","description":"Testosterone is architectural testing framework designed to simplify tests writing and Jersey based applications testing.","archived":false,"fork":false,"pushed_at":"2022-07-07T22:07:53.000Z","size":2145,"stargazers_count":3,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-28T16:06:49.634Z","etag":null,"topics":["helidon-mp-test","jax-rs","jax-rs-test","jersey","jersey-test","jersey2-junit5","junit-jersey","junit-test","tdd-jersey"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stasha.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}},"created_at":"2018-10-19T19:55:13.000Z","updated_at":"2024-07-16T15:59:37.000Z","dependencies_parsed_at":"2022-08-30T11:32:22.428Z","dependency_job_id":null,"html_url":"https://github.com/stasha/testosterone","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/stasha/testosterone","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stasha%2Ftestosterone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stasha%2Ftestosterone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stasha%2Ftestosterone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stasha%2Ftestosterone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stasha","download_url":"https://codeload.github.com/stasha/testosterone/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stasha%2Ftestosterone/sbom","scorecard":{"id":846653,"data":{"date":"2025-08-11","repo":{"name":"github.com/stasha/testosterone","commit":"0ea0c5a2b5bdc6c5844661cdc016d37627656d2d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Eclipse Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"91 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-4gg5-vx3j-xwc7","Warn: Project is vulnerable to: GHSA-735f-pc8j-v9w8","Warn: Project is vulnerable to: GHSA-77rm-9x9h-xj3g","Warn: Project is vulnerable to: GHSA-g5ww-5jh7-63cx","Warn: Project is vulnerable to: GHSA-h4h5-3hr4-j3g2","Warn: Project is vulnerable to: GHSA-wrvw-hg22-4m67","Warn: Project is vulnerable to: GHSA-45hx-wfhj-473x","Warn: Project is vulnerable to: GHSA-h376-j262-vhq6","Warn: Project is vulnerable to: GHSA-6phf-73q6-gh87","Warn: Project is vulnerable to: GHSA-p66x-2cv9-qq3v","Warn: Project is vulnerable to: GHSA-wxr5-93ph-8wr9","Warn: Project is vulnerable to: GHSA-pvp8-3xj6-8c6x","Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v","Warn: Project is vulnerable to: GHSA-9vjp-v76f-g363","Warn: Project is vulnerable to: GHSA-grg4-wf29-r9vv","Warn: Project is vulnerable to: GHSA-269q-hmxg-m83q","Warn: Project is vulnerable to: GHSA-5jpm-x58v-624v","Warn: Project is vulnerable to: GHSA-5mcr-gq6c-3hq2","Warn: Project is vulnerable to: GHSA-cqqj-4p63-rrmm","Warn: Project is vulnerable to: GHSA-wx5j-54mm-rqqq","Warn: Project is vulnerable to: GHSA-f256-j965-7f32","Warn: Project is vulnerable to: GHSA-prj3-ccx8-p6x4","Warn: Project is vulnerable to: GHSA-wm47-8v5p-wjpj","Warn: Project is vulnerable to: GHSA-xpw8-rcwv-8f8p","Warn: Project is vulnerable to: GHSA-389x-839f-4rhx","Warn: Project is vulnerable to: GHSA-xq3w-v528-46rv","Warn: Project is vulnerable to: GHSA-6mjq-h674-j845","Warn: Project is vulnerable to: GHSA-mm9x-g8pc-w292","Warn: Project is vulnerable to: GHSA-p2v9-g2qv-p635","Warn: Project is vulnerable to: GHSA-269g-pwp5-87pp","Warn: Project is vulnerable to: GHSA-g76j-4cxx-23h9","Warn: Project is vulnerable to: GHSA-jcq3-cprp-m333","Warn: Project is vulnerable to: GHSA-m6vm-37g8-gqvh","Warn: Project is vulnerable to: GHSA-w6f2-8wx4-47r5","Warn: Project is vulnerable to: GHSA-rcjc-c4pj-xxrp","Warn: Project is vulnerable to: GHSA-2rvv-w9r2-rg7m","Warn: Project is vulnerable to: GHSA-3p2h-wqq4-wf4h","Warn: Project is vulnerable to: GHSA-5j33-cvvr-w245","Warn: Project is vulnerable to: GHSA-767j-jfh2-jvrc","Warn: Project is vulnerable to: GHSA-7w75-32cg-r6g2","Warn: Project is vulnerable to: GHSA-83qj-6fr2-vhqg","Warn: Project is vulnerable to: GHSA-c9hw-wf7x-jp9j","Warn: Project is vulnerable to: GHSA-f4qf-m5gf-8jm8","Warn: Project is vulnerable to: GHSA-fccv-jmmp-qg76","Warn: Project is vulnerable to: GHSA-ff77-26x5-69cr","Warn: Project is vulnerable to: GHSA-g8pj-r55q-5c2v","Warn: Project is vulnerable to: GHSA-h2fw-rfh5-95r3","Warn: Project is vulnerable to: GHSA-h3gc-qfqq-6h8f","Warn: Project is vulnerable to: GHSA-j39c-c8hj-x4j3","Warn: Project is vulnerable to: GHSA-jgwr-3qm3-26f3","Warn: Project is vulnerable to: GHSA-p22x-g9px-3945","Warn: Project is vulnerable to: GHSA-q3mw-pvr8-9ggc","Warn: Project is vulnerable to: GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GHSA-qxf4-chvg-4r8r","Warn: Project is vulnerable to: GHSA-r6j3-px5g-cq3x","Warn: Project is vulnerable to: GHSA-wc4r-xq3c-5cf3","Warn: Project is vulnerable to: GHSA-wm9w-rjj3-j356","Warn: Project is vulnerable to: GHSA-4j3c-42xv-3f84","Warn: Project is vulnerable to: GHSA-7jqf-v358-p8g7","Warn: Project is vulnerable to: GHSA-cj7v-27pg-wf7q","Warn: Project is vulnerable to: GHSA-hmr7-m48g-48f6","Warn: Project is vulnerable to: GHSA-qh8g-58pp-2wxh","Warn: Project is vulnerable to: GHSA-26vr-8j45-3r4w","Warn: Project is vulnerable to: GHSA-86wm-rrjm-8wh8","Warn: Project is vulnerable to: GHSA-g8m5-722r-8whq","Warn: Project is vulnerable to: GHSA-m394-8rww-3jr7","Warn: Project is vulnerable to: GHSA-m6cp-vxjx-65j6","Warn: Project is vulnerable to: GHSA-p26g-97m4-6q7c","Warn: Project is vulnerable to: GHSA-q4rv-gq96-w7c5","Warn: Project is vulnerable to: GHSA-qw69-rqj8-6qw8","Warn: Project is vulnerable to: GHSA-3gh6-v5v9-6v9j","Warn: Project is vulnerable to: GHSA-gwcr-j4wh-j3cq","Warn: Project is vulnerable to: GHSA-j26w-f9rq-mr2q","Warn: Project is vulnerable to: GHSA-c43q-5hpj-4crv","Warn: Project is vulnerable to: GHSA-77xx-rxvh-q682","Warn: Project is vulnerable to: GHSA-24rp-q3w6-vc56","Warn: Project is vulnerable to: GHSA-562r-vg33-8x8h","Warn: Project is vulnerable to: GHSA-673j-qm5f-xpv8","Warn: Project is vulnerable to: GHSA-727h-hrw8-jg8q","Warn: Project is vulnerable to: GHSA-88cc-g835-76rp","Warn: Project is vulnerable to: GHSA-r38f-c4h4-hqq2","Warn: Project is vulnerable to: GHSA-v7wg-cpwc-24m4","Warn: Project is vulnerable to: GHSA-rc2q-x9mf-w3vf","Warn: Project is vulnerable to: GHSA-3mc7-4q67-w48m","Warn: Project is vulnerable to: GHSA-98wm-3w3q-mw94","Warn: Project is vulnerable to: GHSA-9w3m-gqgf-c4p9","Warn: Project is vulnerable to: GHSA-c4r9-r8fh-9vj2","Warn: Project is vulnerable to: GHSA-hhhw-99gj-p3c3","Warn: Project is vulnerable to: GHSA-mjmj-j48q-9wg2","Warn: Project is vulnerable to: GHSA-rvwf-54qp-4r6v","Warn: Project is vulnerable to: GHSA-w37g-rhq8-7m4j"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T21:38:05.730Z","repository_id":37280962,"created_at":"2025-08-23T21:38:05.730Z","updated_at":"2025-08-23T21:38:05.730Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["helidon-mp-test","jax-rs","jax-rs-test","jersey","jersey-test","jersey2-junit5","junit-jersey","junit-test","tdd-jersey"],"created_at":"2026-01-14T02:43:47.473Z","updated_at":"2026-01-14T02:43:47.984Z","avatar_url":"https://github.com/stasha.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Testosterona cartoon](https://github.com/stasha/testosterone/blob/master/testosterona.png)\n\n\n# testosterone\nis architectural testing framework designed to simplify tests writing and Jersey based applications testing.\u003cbr /\u003e\nAlso, it simplifies writing \"free-form\" or \"cowboy\" tests. Beside testing it is ideal for learning/experimenting with Jersey, Helidon or CDI.\n\n[![Build Status](https://travis-ci.org/stasha/testosterone.svg?branch=master)](https://travis-ci.org/stasha/testosterone)\n[![CircleCI](https://circleci.com/gh/stasha/testosterone/tree/master.svg?style=svg)](https://circleci.com/gh/stasha/testosterone/tree/master)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/info.stasha/testosterone/badge.svg)](https://maven-badges.herokuapp.com/maven-central/info.stasha/testosterone)\n[![Coverage Status](https://coveralls.io/repos/github/stasha/testosterone/badge.svg)](https://coveralls.io/github/stasha/testosterone)\n[![Maintainability](https://api.codeclimate.com/v1/badges/2aa577a0b1c433309bf0/maintainability)](https://codeclimate.com/github/stasha/testosterone/maintainability)\n\n\n\nTestosterone is built around idea where components are tested from ground up ending with joined tests into integration.\n1. [Test DAO - against in-memory or external DB](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/task/dao/TaskDaoTest.java)\n2. [Test service - using mocks](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/task/service/TaskServiceTest.java)\n3. [Test resource - using mocks](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/task/resource/TaskResourceTest.java)\n4. [Integration test - against embedded server, in-memory or external DB](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/TaskEndpointIntegrationTest.java)\n5. [Integration test - against any external environment](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/TaskEndpointExternalIntegrationTest.java)\n\nTake a look at [example](https://github.com/stasha/testosterone/tree/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration) code.\n\n\n### Testosterone supports\n- **ALL Jersey versions from 2.1 to 2.29.1**\n- **ALL Helidon versions from 1.0.0 to 1.4.1**\n    - [Includes CDI mocking and spying](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/helidon/HelidonTest.java)\n###\n- testing frameworks \n    - [JUnit4](https://github.com/stasha/testosterone/tree/master/src/main/java/info/stasha/testosterone/jersey/junit4) \n    - [JUnit5](https://github.com/stasha/testosterone/tree/master/src/main/java/info/stasha/testosterone/jersey/junit5)\n    - [TestNG](https://github.com/stasha/testosterone/tree/master/src/main/java/info/stasha/testosterone/jersey/testng)\n- embedded servers \n    - [Jetty](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/servers/JettyServerConfig.java)\n    - [Tomcat](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/servers/TomcatServerConfig.java)\n    - [Grizzly](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/servers/GrizzlyServerConfig.java) \n- in-memory databases \n    - [H2](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/db/H2Config.java)\n    - [Derby](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/db/DerbyConfig.java)\n    - [HSQLDB](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/db/HsqlDbConfig.java)\n- external databases \n    - [Postgres](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/db/PostgresConfig.java) \n    - [MySql](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/db/MySqlConfig.java) \n- servlet components in Jetty and Tomcat\n    - [Servlets](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/servlet/ServletJettyTest.java)\n    - [Filters](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/servlet/servletfilter/ServletFilterJettyTest.java)\n    - [Listeners](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/servlet/servletlistener/ServletListenerJettyTest.java)\n    - [Context Params](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/servlet/servletcontextparams/ServletContextParamsJettyTest.java)\n- context injections\n    - default\n        - [all provided by Jersey](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/injectables/InjectablesTest.java)\n    - additional\n        - [Connection - injects DB connection](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/task/dao/TaskDaoTest.java)\n        - [DbConfig - injects DB configuration (useful for obtaining Connection or DataSource)](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/db/HsqlDbConfigTest.java)\n        - [Testosterone - injects current executing test (useful for developing other components)](https://github.com/stasha/testosterone/blob/master/src/main/java/info/stasha/testosterone/jersey/inject/SpyInjectionResolver.java)\n- additional annotations\n    - [@Mock - injects mocked object](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/injectables/MockInjectTest.java)\n    - [@Spy - injects spied object](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/injectables/SpyInjectTest.java)\n    - [@Value - injects value from resource (properties)](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/injectables/ValueInjectionTest.java)\n    - [@LoadFile - injects String or InputStream](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/injectables/LoadFileTest.java) \n    - [@Request - sends request to specified URL](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/request/RequestTest.java)\n    - [@Requests - groups @Request annotations](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/jersey/request/RequestTest.java)\n    - [@Dependencies - includes other test classes as dependencies](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/task/dao/TaskDaoTest.java)\n    - [@Integration - includes other test classes into local integration test](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/TaskEndpointIntegrationTest.java)\n- life-cycle callbacks\n    - [beforeServerStart](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/lifecycle/TestLifeCyclePerClassTest.java)\n    - [afterServerStart](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/lifecycle/TestLifeCyclePerClassTest.java)\n    - [beforeServerStop](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/lifecycle/TestLifeCyclePerClassTest.java)\n    - [afterServerStop](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/lifecycle/TestLifeCyclePerClassTest.java)\n- register custom ServerConfig, DbConfig and TestConfig configurations\n    - globally\n        - by setting system properties\n            - testosterone.default.server.config\n            - testosterone.default.db.config\n            - testosterone.default.test.config\n        - by using ServiceLoader mechanism\n            - /META-INF/services/info.stasha.testosterone.ServerConfig\n            - /META-INF/services/info.stasha.testosterone.DbConfig\n            - /META-INF/services/info.stasha.testosterone.TestConfig\n    - locally\n        - [by annotating test class with @Configuration annotation](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/user/dao/UserDaoTest.java)\n- clean code configuration separation with standardized methods\n    - [configure(...)](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/user/dao/UserDaoTest.java)\n    - [configureMocks(...)](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/user/dao/UserDaoTest.java)\n- integration testing\n    - [locally on embedded server with in-memory or external DB](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/TaskEndpointIntegrationTest.java)\n    - [remote](https://github.com/stasha/testosterone/blob/master/src/test/java/info/stasha/testosterone/jersey/junit4/integration/test/TaskEndpointExternalIntegrationTest.java)\n- tests and in test endpoints can be executed from browser by setting configuration property ```stopServerAfterTestEnds=false```\n\n### Install using maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003einfo.stasha\u003c/groupId\u003e\n    \u003cartifactId\u003etestosterone\u003c/artifactId\u003e\n    \u003cversion\u003e${testosterone.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Downlod from\n```\nhttps://repo.maven.apache.org/maven2/info/stasha/testosterone/\n```\n\n### Minimum dependencies for running tests\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.glassfish.jersey.containers\u003c/groupId\u003e\n    \u003cartifactId\u003ejersey-container-grizzly2-servlet\u003c/artifactId\u003e\n    \u003cversion\u003e2.27\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.glassfish.jersey.containers\u003c/groupId\u003e\n    \u003cartifactId\u003ejersey-container-grizzly2-http\u003c/artifactId\u003e\n    \u003cversion\u003e2.27\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- Required for Jersey version 2.26 and higher. For lower versions\nthis dependency should be removed because it makes conflicts --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.glassfish.jersey.inject\u003c/groupId\u003e\n    \u003cartifactId\u003ejersey-hk2\u003c/artifactId\u003e\n    \u003cversion\u003e2.27\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n    \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n    \u003cversion\u003e3.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003einfo.stasha\u003c/groupId\u003e\n    \u003cartifactId\u003etestosterone\u003c/artifactId\u003e\n    \u003cversion\u003e3.0.1\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ejunit\u003c/groupId\u003e\n    \u003cartifactId\u003ejunit\u003c/artifactId\u003e\n    \u003cversion\u003e4.12\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n\n### Minimum code required\n\n#### JUnit4\n```java\nimport info.stasha.testosterone.jersey.junit4.Testosterone;\nimport info.stasha.testosterone.junit4.TestosteroneRunner;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n@RunWith(TestosteroneRunner.class)\npublic class JUnit4Test implements Testosterone {\n    \n    @Test\n    public void test(){\n    }\n}\n```\n\n#### JUnit5\n```java\nimport info.stasha.testosterone.jersey.junit5.Testosterone;\nimport org.junit.jupiter.api.Test;\n\npublic class JUnit5Test implements Testosterone {\n \n    @Test\n    public void test(){\n    }\n}\n```\n\n#### TestNG\n```java\nimport info.stasha.testosterone.jersey.testng.Testosterone;\nimport org.testng.annotations.Test;\n\npublic class TestNGTest implements Testosterone {\n \n    @Test\n    public void test(){\n    }\n}\n```\n\n#### Test class configuration defaults\n```java\n@Configuration(\n  baseUri = \"http://localhost/\", \n  httpPort = 9998, \n  testConfig = JerseyTestConfig.class, \n  dbConfig = H2Config.class, \n  serverConfig = JettyServerConfig.class, \n  runServer = true, \n  runDb = false, \n  startServer = StartServer.PER_CLASS,\n  stopServerAfterTestEnds = true\n)\npublic class TestNGTest implements Testosterone {\n \n    @Test\n    public void test(){\n    }\n}\n```\n## Examples\n#### DAO test\n```java\n@RunWith(TestosteroneRunner.class)\n@Dependencies(\n        UserDaoTest.class\n)\n@Configuration(startServer = StartServer.PER_TEST_METHOD, runDb = true)\npublic class TaskDaoTest implements Testosterone {\n\n    private final String createTasksTable = \"CREATE TABLE tasks (\\n\"\n            + \"  id BIGINT(11) NOT NULL auto_increment PRIMARY KEY,\\n\"\n            + \"  title VARCHAR(56) NOT NULL,\\n\"\n            + \"  description VARCHAR(56) NOT NULL,\\n\"\n            + \"  done BOOLEAN NOT NULL,\\n\"\n            + \"  users_user_id BIGINT(11) NOT NULL,\\n\"\n            + \"  created_at DATETIME,\\n\"\n            + \"  updated_at DATETIME,\\n\"\n            + \"  FOREIGN KEY (users_user_id) REFERENCES users(id)\\n\"\n            + \"  )\";\n\n    @Context\n    Connection conn;\n\n    @Context\n    private TaskDao taskDao;\n\n    @Override\n    public void configure(AbstractBinder binder) {\n        binder.bindFactory(TaskDaoFactory.class).to(TaskDao.class).in(RequestScoped.class).proxy(true).proxyForSameScope(false);\n    }\n\n    @Override\n    public void configure(DbConfig config) {\n        config.add(\"createTasksTable\", createTasksTable);\n    }\n\n    @Override\n    public void configureMocks(DbConfig config) {\n        config.add(\"addMockTasks\", \"insert into tasks (title, description, done, users_user_id) values \"\n                + \"('Create Task Test1', 'Testing TaskDao1', false, 1),\"\n                + \"('Create Task Test2', 'Testing TaskDao2', true, 2),\"\n                + \"('Create Task Test3', 'Testing TaskDao3', false, 3)\");\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        assertEquals(\"Task list should contain 3 tasks\", 3, taskDao.getAllTasks().size());\n    }\n\n    @After\n    public void tearDown() throws Exception {\n        conn.prepareStatement(\"drop table tasks\").executeUpdate();\n    }\n\n    @Test\n    public void readAllTasks() throws Exception {\n        taskDao.createTask(new Task(\"Create Task Test 4\", \"Testing TaskDao 2\", Boolean.FALSE, new User(1L)));\n\n        List\u003cTask\u003e tasks = taskDao.getAllTasks();\n        assertEquals(\"Task list should contain 4 tasks\", 4, tasks.size());\n    }\n\n    @Test\n    public void readTask() throws Exception {\n        Task dbtask = taskDao.getTask(new Task(3L));\n        assertNotNull(\"Returned task from db should not be null\", dbtask);\n    }\n\n    @Test\n    public void updateTask() throws Exception {\n        this.taskDao.updateTask(new Task(2L).setTitle(\"Update Task Test\").setDescription(\"Updating testing TaskDao\").setDone(Boolean.TRUE));\n\n        Task dbtask = taskDao.getTask(new Task(2L));\n        assertNotNull(\"Returned task sould not be null\", dbtask);\n        assertEquals(\"Title should be updated\", \"Update Task Test\", dbtask.getTitle());\n        assertEquals(\"Description should be updated\", \"Updating testing TaskDao\", dbtask.getDescription());\n        assertEquals(\"Done should be true\", true, dbtask.getDone());\n    }\n\n    @Test\n    public void deleteTask() throws Exception {\n        this.taskDao.deleteTask(new Task(1L));\n\n        Task dbtask = taskDao.getTask(new Task(1L));\n        assertNull(\"Returned task should be null\", dbtask);\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void createSqlException() throws SQLException {\n        this.taskDao.createTask(new Task());\n    }\n\n}\n```\n#### Service test\n```java\n@RunWith(TestosteroneRunner.class)\npublic class TaskServiceTest implements Testosterone {\n\n    @Context\n    private TaskService taskService;\n\n    @Context\n    private TaskDao taskDao;\n\n    private final Task task = new Task(\"New Task\", \"New Task Description\", false).setId(1L);\n\n    @Override\n    public void configure(AbstractBinder binder) {\n        binder.bindFactory(TaskServiceFactory.class).to(TaskService.class).in(RequestScoped.class).proxy(true).proxyForSameScope(false);\n    }\n\n    @Override\n    public void configureMocks(AbstractBinder binder) {\n        binder.bindFactory(FactoryUtils.\u003cTaskDao\u003emock(TaskDaoFactory.class)).to(TaskDao.class).in(Singleton.class);\n    }\n\n    public \u003cT\u003e T verify(T mock, int invocations) {\n        return Mockito.verify(mock, times(invocations));\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void createTest() throws Exception {\n        taskService.createTask(new Task(1L));\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void createTest2() throws Exception {\n        taskService.createTask(null);\n    }\n\n    @Test\n    public void createTest3() throws Exception {\n        taskService.createTask(task.setId(null));\n        verify(taskDao, 1).createTask(task.setId(null));\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void readTest() throws Exception {\n        taskService.getTask(new Task());\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void readTest2() throws Exception {\n        taskService.getTask(null);\n    }\n\n    @Test\n    public void readTest3() throws Exception {\n        taskService.getTask(task);\n        Mockito.verify(taskDao, times(1)).getTask(task);\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void updateTest() throws Exception {\n        taskService.updateTask(new Task());\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void updateTest2() throws Exception {\n        taskService.updateTask(null);\n    }\n\n    @Test\n    public void updateTest3() throws Exception {\n        taskService.updateTask(task);\n        Mockito.verify(taskDao, times(1)).updateTask(task);\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void deleteTest() throws Exception {\n        taskService.deleteTask(new Task());\n    }\n\n    @Test(expected = NullPointerException.class)\n    public void deleteTest2() throws Exception {\n        taskService.deleteTask(null);\n    }\n\n    @Test\n    public void deleteTest3() throws Exception {\n        taskService.deleteTask(task);\n        Mockito.verify(taskDao, times(1)).deleteTask(task);\n    }\n\n}\n```\n#### Resource test\n```java\n@RunWith(TestosteroneRunner.class)\npublic class TaskResourceTest implements Testosterone {\n\n    protected final Task task = new Task(3L, \"Title\", \"Description\", false);\n    protected final Task createTask = new Task(\"Title\", \"Description\", false);\n    public Entity taskEntity = Entity.json(task);\n    public Entity createTaskEntity = Entity.json(createTask);\n\n    private final TaskResource taskResource = Mockito.spy(new TaskResource());\n\n    @Context\n    protected TaskService taskService;\n\n    @Override\n    public void configure(ResourceConfig config) {\n        config.register(taskResource);\n    }\n\n    @Override\n    public void configureMocks(AbstractBinder binder) {\n        binder.bindFactory(FactoryUtils.\u003cTaskService\u003emock(TaskServiceFactory.class)).to(TaskService.class).in(Singleton.class);\n    }\n\n    public \u003cT\u003e T verify(T mock, int invocations) {\n        return Mockito.verify(mock, times(invocations));\n    }\n\n    @Test\n    @Request(url = \"task\", method = GET, expectedStatus = {200, 204})\n    public void getAllTasks(Response resp) throws Exception {\n        verify(taskResource, 1).getAllTasks();\n        verify(taskService, 1).getAllTasks();\n    }\n\n    @Test\n    @Request(url = \"task\", method = POST, entity = \"taskEntity\", expectedStatus = {200, 204})\n    public void createTask(Response resp) throws Exception {\n        verify(taskResource, 1).createTask(Matchers.refEq(task));\n        verify(taskService, 1).createTask(Matchers.refEq(task));\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = GET, expectedStatus = {200, 204})\n    public void getTask(Response resp) throws Exception {\n        verify(taskResource, 1).getTask(any(Task.class));\n        verify(taskService, 1).getTask(any(Task.class));\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = PUT, entity = \"taskEntity\", expectedStatus = {200, 204})\n    public void updateTask(Response resp) throws Exception {\n        verify(taskResource, 1).updateTask(Matchers.refEq(task));\n        verify(taskService, 1).updateTask(Matchers.refEq(task));\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = DELETE, expectedStatus = {200, 204})\n    public void deleteTask(Response resp) throws Exception {\n        verify(taskResource, 1).deleteTask(any(Task.class));\n        verify(taskService, 1).deleteTask(any(Task.class));\n    }\n\n}\n```\n#### Local integration test\n```java\n@Integration({\n    TaskResourceTest.class,\n    TaskServiceTest.class,\n    TaskDaoTest.class,\n    UserResourceTest.class,\n    UserServiceTest.class,\n    UserDaoTest.class\n})\n@RunWith(TestosteroneRunner.class)\n@Configuration(runDb = true)\npublic class TaskEndpointIntegrationTest implements Testosterone {\n\n    protected TaskResource taskResource;\n    protected final Task task = new Task(3L, \"Title\", \"Description\", false, new User(2L));\n    protected final Task createTask = new Task(\"Title\", \"Description\", false, new User(1L));\n    public Entity taskEntity = Entity.json(task);\n    public Entity createTaskEntity = Entity.json(createTask);\n\n    @Before\n    public void setUp() throws SQLException {\n        target(\"user\").request().post(Entity.json(new User(\"Jon\", \"Doe\", 23)));\n    }\n\n    @Test\n    @Request(url = \"task\", method = GET, expectedStatus = {200, 204})\n    public void getAllTasks(Response resp) throws Exception {\n    }\n\n    @Test\n    @Request(url = \"task\", method = POST, entity = \"taskEntity\", expectedStatus = {500})\n    public void failCreateTask(Response resp) throws Exception {\n    }\n\n    @Test\n    @Request(url = \"task\", method = POST, entity = \"createTaskEntity\", expectedStatus = {200, 204})\n    public void createTask(Response resp) throws Exception {\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = GET, expectedStatus = {200, 204})\n    public void getTask(Response resp) throws Exception {\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = PUT, entity = \"taskEntity\", expectedStatus = {200, 204})\n    public void updateTask(Response resp) throws Exception {\n    }\n\n    @Test\n    @Request(url = \"task/1\", method = DELETE, expectedStatus = {200, 204})\n    public void deleteTask(Response resp) throws Exception {\n    }\n\n}\n```\n#### External/remote integration test\n```java\n// Just extend local integration test and change configuration\n@Configuration(baseUri = \"http://myapp.com/\", httpPort = 80, runServer = false)\npublic class TaskEndpointExternalIntegrationTest extends TaskEndpointIntegrationTest {\n\n}\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstasha%2Ftestosterone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstasha%2Ftestosterone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstasha%2Ftestosterone/lists"}