<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Not so long ago I would’ve gone with #3 immediately, but lately my co-worker <a href="https://github.com/marcelog" class="">Marcelo Gornstein</a> is slowly persuading me of using something like #2.<div class="">I think he’s about to write a blog post exactly about that.<br class=""><div class="">
<div style="color: rgb(0, 0, 0); font-family: 'Trebuchet MS'; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><span id="docs-internal-guid-e691a4cc-056a-0210-b8b7-ea8d87d888ad" class=""><span style="font-size: 11pt; font-family: Arial; font-weight: 700; font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;" class=""><br class="Apple-interchange-newline"><hr class=""></span></span><div class=""><b class=""><i class=""><a href="http://about.me/elbrujohalcon" class="">Brujo Benavides</a></i></b></div></div></div><div style="color: rgb(0, 0, 0); font-family: 'Trebuchet MS'; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><b class=""><br class=""></b></div><br class="Apple-interchange-newline">
</div>
<div><br class=""><blockquote type="cite" class=""><div class="">On 28 Mar 2018, at 10:18, Sölvi Páll Ásgeirsson <<a href="mailto:solvip@gmail.com" class="">solvip@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi all<br class=""><br class="">I'm wondering about various different approaches to writing testable<br class="">Erlang and I'd be super interested in hearing about how you approach<br class="">this.<br class=""><br class="">As a concrete example, let's assume that we're building software that<br class="">talks to financial exchanges.<br class="">When submitting orders, you might need to map symbols to/from order<br class="">book ids, so you run a named gen_server that:<br class=""><br class="">- Knows how to map an order book id to symbol (i.e., 1234 -> ERIC)<br class="">- Knows how to map symbol to id (ERIC -> 1234)<br class="">- Knows how to refresh it's map periodically from an external service,<br class="">such as a database or whatever<br class=""><br class="">Then you want to test your protocol handler, which depends on this id<br class="">mapping server, but you don't want to make an expensive call to an<br class="">external service for every test you run, so you want to provide fake<br class="">data.<br class=""><br class="">I see a few different possible approaches to orchestrate testing of<br class="">this, but I'm having a hard time figuring out which of these I should<br class="">follow in general:<br class=""><br class="">1. You can start the protocol handler with a parameter, IdMapMod ::<br class="">module(), and implement a stub_idmap module that knows how to map<br class="">to/from certain ids to use in your tests.<br class="">The downside of this is that all calls from the protocol handler to<br class="">the id map must extract a dynamic module name from the state, and then<br class="">you lose dialyzer, xref, ...<br class="">Another downside(or upside?) is that you won't actually perform any<br class="">actual calls to your id mapping server.<br class=""><br class="">2. You can start the id mapping server with a parameter,<br class="">ExternalServiceMod :: module(), and fake out the external service call<br class="">only.<br class="">Then your tests of the protocol handler would actually exercise the id<br class="">mapping server; but it's calls to an external service would be<br class="">answered with a fake stub.<br class="">This way you get the benefit of dialyzer + xref as your protocol<br class="">handler simply calls id_map:symbol_to_id/1 or whatever.<br class=""><br class="">3. You can use a mocking library such as meck to do something very<br class="">similar to either of the two above things.<br class="">In past lives using other languages, I've generally developed a<br class="">distaste for mocking, as I've felt that it can create brittle tests.<br class="">Generally, I think I'd prefer to be able to test things in terms of<br class="">interfaces, but I might be swayed otherwise.<br class=""><br class="">Is there anything else I'm missing?  How do you write testable Erlang?<br class=""> Is there a general approach you follow?<br class=""><br class="">Thanks & regards<br class="">Sölvi Páll Á<br class="">_______________________________________________<br class="">erlang-questions mailing list<br class=""><a href="mailto:erlang-questions@erlang.org" class="">erlang-questions@erlang.org</a><br class="">http://erlang.org/mailman/listinfo/erlang-questions<br class=""></div></div></blockquote></div><br class=""></div></body></html>