Behave the way the user expects.
Helps define requirements of what you are looking to build.
Others can easily understand.
Backend can have bugs that you will never find out about until something goes wrong
Easy to modify or extend, refactor
# Write a failing test (fail, stop)
# Write a success test (passing)
## functionality may not be complete, but working
null test → pass
stub required objects → test presence → pass
write functionality spec → test failure → create functionality in actual file → test → pass
Test structure should follow:
Setup
Method
Validation/Assertion
Avoid implementation of external dependencies in unit tests.
Using things like dependency injection (and shallow-mocking the dependencies), you can avoid relying on the actual implementations to run properly for the test to pass.
// external dependencies and its implementation tested import ( someExternalFunction ) func testTightCoupling(someParam: string) boolean { testValue := someParam // calling actual implementation (bad) someExternalFunction(testValue); // assertion } // shallow dependencies using mock return value const mockedServiceMethod = mock(someExternalFunction) func testLooseCoupling() boolean { testValue := someParam // calling mocked implementation mockedServiceMethod(testValue) }