-
Notifications
You must be signed in to change notification settings - Fork 33
Guidelines
- Test coverage must remain above 90% for both line and branch coverage.
- Use ScalaTest for all tests
- Use the
AkkaTestJawn
for all tests in money-core that tests actors - Use ScalaTest
WordSpec
for unit tests and Akka tests - Use ScalaTest
FeatureSpec
for integration tests - Use ScalaTest
GivenWhenThen
to add clarity to all tests when clarity is needed - Use the Akka Testkit for doing all Actor testing
- Use
Mockito
when needed. We tend to use more integrated functional test (Akka Testkit, Integration Tests) as opposed to using Mocks. If you have to mock, make sure that you don't have a suitable way to do the same test using the Testkit or Integration tests
We do not use any dependency injection library in Money. This is done specifically to limit the dependencies that are sucked into Money.
But, we do need to have a way to unit test, so we will need at times need to create test stand ins or use mock objects.
- Use CONSTRUCTOR arguments to pass in depedencies. Yes, this is the ultimate dependency injection mechanism!
- Use the
ActorMaker
trait for Actors in order to create child actors, Use theAkkaTestJawn
to test this. We have a nice little harness that we use in order to capture child actor creation and substitue with test probes instead. Use it, or suffer the consequences (consequences TBD). - Limit your use of advanced injection techniques like the Cake pattern. Yes, the cake pattern and self type annotations are super cool, but they should be consistently applied across the codebase. If you cannot use a constructor argument or ActorMaker, you should have a darn good reason.
The motivation here is purely readability. While the SNAKE_CASE
makes something stand out, using them regularly makes
the code difficult to read.
-
DO name your constant like
val FormatString = "%s.format.%s"
- DON'T name your constant like snake case `val FORMAT_STRING = "%s.format.%s"
-
DO
def doSomething(foo:String)
-
DON'T
def this_is_scala_not_python(jerk:You)
get
is a Javabean standard, and clutters the code. It is much easier to read person.firstName
as opposed to getPerson.getFirstName
parens add unnecessary clutter to the code, especially when retrieving a value. Again, person.firstName
is much more readable than person().firstName()
This even applies to java getters, so javabean.getField
as opposed to javabean.getField()
, and obj.toString
as opposed to obj.toString()
When saving data to a persistent store:
-
DO call the method
saveData(something:Person)
-
DON'T call the method
data(something:Person)
-
DO call the function
machine.reboot()
-
DON'T call the function
machine.reboot
Use Joda's DateTimeUtils.currentTimeMillis() instead of System.currentTimeMillis(). This supports testing.
We don't handle nulls (or at least we do everything in our power to avoid them). If it is possible that a variable or member to not have a value,
then use the scala.Option
. You see Option everywhere in the code, get used to it, it is awesome.
-
DO
class Person(val middleName:Option[String] = None)
-
DON'T
class Person(val middleName:String = null)
(if you do this, then you will be made an example of in front of the world
case classes are a super duper scala construct that will automatically generate properties for a class, generate equals and hashcode, and do other awesome stuff. The most awesome thing they can easily do is being used in "pattern matching". They also are used by other libraries like JSON and XML. So get used to them, and feel good about it.
-
DO
case class Person(firstName:String,lastName:String)
-
DON'T
class Person(val firstName:String, val lastName: String)
- Overview
- Configuration
- Logging Setup
- Performance Considerations
- Java Users Guide
- Scala Users Guide
- Modules
- Contributing