You will fail Java coding test if you miss this essential skill
How do you make sure your piece of code works according to the requirements?
I interviewed many candidates and tested their coding skills so far and only a few candidates got recommended to the next stage for the position of hands-on software engineer.
Is the coding exercise too challenging? I don’t think so because most candidates were able to solve the problems.
Many candidates failed to answer this question:
How do you make sure your piece of code works according to the requirements?
Sad to say, many potential candidates fail to answer this question. As a result, fail the interview even though it is a demonstration of outstanding problem solving skills.
Many candidates walk through the code line by line and explain how it works. It makes sense, however, it is not the right answer even though the code seems logical.
You are not 100% sure the code logic work fine without testing.
When interviewers ask this question, candidates are in fact expected to write unit test cases instead of explaining the code logic.
Why don’t you just straightforwardly ask the candidate to write unit tests? The question is to check if the candidates have the awareness of code quality.
It is an effective way to check whether the candidates are hands-on software engineers.
Why is writing test code important?
Software engineers are responsible for implementing business functions as well as writing tests that make sure code logic works accordingly.
Before the era of test automation, software engineers complete coding and hand it over to a quality team to perform the testing. Tests are done manually and testers mark down the test results for software engineers to follow up in case of any issues.
In the modern software production line, tests are mostly automated. Software engineers write test codes that verify the system behavior.
Therefore, it is not possible that you don’t write any unit test code if you claim yourself to be a hands-on software engineer.
TDD or not does not matter, you goal is to prove the system logic meets the requirements.
Alright. You know that writing test code is an important skill. How to write test code like a professional coder?
A simple exercise
Let’s take a look at this simple coding test example:
Given an external account balance store which persist the current account balance
Write a function that takes inputs:
- Transaction (deposit / withdrawal)
- The current balance
Then, output the updated balance back to the account balance store.
The function should reject invalid transactions (e.g. transaction with negative deposit amount) and transactions that result in negative balance
Assuming that you have done the coding, how do you verify transaction process logic is correct?
Here are my advices to candidates who are preparing for coding tests.
Don’t write unit test using main function
Rule #1 does unit tests in a proper way. Writing unit tests in a main function reveals that you are not used to writing unit tests. Although it is obvious, I observed many candidates attempt to write unit tests in a main function.
JUnit is the de facto when it comes to unit tests in Java. While using JUnit @Test annotation is handy and simple, why bother writing test code in main()? Looking at the method signature, the difference is trivial. However, the use of JUnit @Test allows us to clearly define multiple test scenarios.
Main function
public static void main(String[] args) {
// … test code …
}JUnit
@Test
void testTransactionProcess() {
// … test code …
}Clearly define test scenarios
It is expected to verify the system logic with test scenarios covering both normal and error cases. Bundling multiple test scenarios into one single test is definitely not a good sign.
Using method name as the scenario description is a common practice. For example,
test<Scenario> pattern
testNegativeDeposit()testPositiveDeposit()testPositiveDepositWithNoAccountBalance()
Given-When-Then pattern
givenNegativeDeposit_whenProcessTransaction_thenRejectTransaction()givenPositiveDeposit_whenProcessTransaction_thenAccountBalanceUpdated()givenNoAccountBalanceAndPositiveDeposit_whenProcessTransaction_thenAccountBalanceUpdated()
Alternatively, use @DisplayName annotation if you think long method names are too clumsy.
Setup mocking if necessary
It is not common to expect candidates to write unit tests with mocking as part of job interview coding exercise. However, some companies cover it in their coding exercises according to my experience.
Mocking is a common technique that unit tests focus on the target system logic and create stub for external components.
With account balance store as the given external component, unit test mocks the output of getBalance() that returns the mocked value of the current balance. Don’t forget to verify the method call on the mock object if the system logic calls it as part of the output.
Here is the simple skeleton of the mock setup using Mockito library
@ExtendWith(MockitoExtension.class)
public class TransactionProcessorTest {
@Mock
private AccountBalanceStore accountBalanceStore;
@InjectMocks
private TransactionProcessor transactionProcessor;
@Test
void testPositiveDeposit() {
String accountNumber = "123";
BigDecimal currentAccountBalance = BigDecimal.ONE;
BigDecimal expectedAccountBalance = BigDecimal.TEN;
when(accountBalanceStore.getBalance(accountNumber))
.thenReturn(currentAccountBalance);
// ... do test on TransactionProcessor …
verify(accountBalanceStore).saveBalance(accountNumber, expectedAccountBalance);
}
}Use AssertJ library like a pro
The step to verify the system logic output is call assertion in unit tests. Many candidates know that they need to assert the output but they are not familiar with the usage of assertion method calls.
Many candidates struggle with looking for the right method to do the assertion using JUnit and some even use keyword assert in Java language.
To impress the interviewers that you are a hands-on software engineer, I would highly recommend using the AssertJ library.
@Test
void testSimpleDeposit() {
Transaction deposit = // deposit transaction
BigDecimal expectedAccountBalance = // expected account balance
TransactionProcessor transactionProcessor = new TransactionProcessor();
BigDecimal updateBalance = transactionProcessor.handle(deposit);
// AssertJ assertion
assertThat(updateBalance).isEqualTo(expectedAccountBalance);
}Final Thoughts
Unit testing is equally important as system logic coding. Automated unit tests are the efficient and systematic way to verify the system logic. Writing tests would take roughly 40% of total development time. The hands-on skills of writing test code is crucial to a successful software engineer. Therefore, some companies expect candidates to write unit test code as part of a job interview.
Nevertheless, many candidates focus on problem solving skills but ignore the importance of unit testing when they prepare for the coding exercise interview. They fail to get through the coding exercise not because of problem solving skills but their poor performance of unit testing.
Whether you are a hands-on software engineer or not, don’t forget to spend time on practising unit tests for job interview preparation. Here is the list of quick tips:
- Write unit test in a proper way
- Clearly organize test scenarios
- Setup mock if necessary
- Assert output using fluent method calls




