{"id":16701640,"url":"https://github.com/coryodaniel/organize-and-test-genservers","last_synced_at":"2026-04-26T17:31:58.625Z","repository":{"id":66508478,"uuid":"318314878","full_name":"coryodaniel/organize-and-test-genservers","owner":"coryodaniel","description":"Just a repo of how I organize and test genservers","archived":false,"fork":false,"pushed_at":"2020-12-03T20:47:06.000Z","size":5,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-31T04:59:58.612Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coryodaniel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-03T20:43:36.000Z","updated_at":"2020-12-03T20:47:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"fa61c4f6-88c3-420e-b32e-f74ec5a90b40","html_url":"https://github.com/coryodaniel/organize-and-test-genservers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/coryodaniel/organize-and-test-genservers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryodaniel%2Forganize-and-test-genservers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryodaniel%2Forganize-and-test-genservers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryodaniel%2Forganize-and-test-genservers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryodaniel%2Forganize-and-test-genservers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coryodaniel","download_url":"https://codeload.github.com/coryodaniel/organize-and-test-genservers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryodaniel%2Forganize-and-test-genservers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32307011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T17:23:19.671Z","status":"ssl_error","status_checked_at":"2026-04-26T17:23:19.195Z","response_time":129,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-10-12T18:44:58.978Z","updated_at":"2026-04-26T17:31:58.598Z","avatar_url":"https://github.com/coryodaniel.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# How I test and layout genservers\n\n## Set up and run tests \u0026 type checks\n\nI tested a few different ways:\n\n*DocTests on the public API of the GenServer (`lib/project.ex`)*\n\nI like to consider my modules in the public API's directory to be \"semi private\" and test from the public interface.\n\nI use dependency injection to put in the state, and I start a named instances of the GenServer for test isolation so tests can be async.\n\nThis validates the public API works as documented.\n\n*ExUnit tests on the public API `test/tgs/project_test.exs`*\n\nSimilar to the tests in DocTest, but I use the exunit test ID as the genserver name.\n\nThis lets you have more involved tests that via DocTest, but then it doesn't validate the documentation. YMMV.\n\n*DocTests on the functional logic of the GenServer (`lib/tgs/project/logic.ex`)\n\nI don't like this since its a \"semi private\" model, but some people appreciate the functional tests without involving a genserver.\n\n## How I layout GenServers\n\n* `lib/project.ex` - Public API for the genserver\n* `lib/project/logic.ex` - The business logic of the feature\n* `lib/project/repository.ex` - The struct and type for the state of the genserver\n* `lib/project/server.ex` - The genserver callback code\n\nI consider any genserver callback a smell if its more than a single line of code, because all of the logic should be in `logic.ex`, except when doing a mutating `handle_call/3`.\n\n\n```shell\nmix deps.get\n\nmix test --cover\nmix dialyzer\n```\n\n## Interact w/ project storage\n\nRun `iex -S mix`:\n\n```elixir\n{:ok, project} = Tgs.Project.start_link()\nTgs.Project.list_projects(project)\nTgs.Project.create_project(project, \"my project\")\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoryodaniel%2Forganize-and-test-genservers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoryodaniel%2Forganize-and-test-genservers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoryodaniel%2Forganize-and-test-genservers/lists"}