-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create exercises for lab08 and update config.yml (#133)
* wip on BankAccount testing * implement the initial tests * add a death note * implement a Death Note * implement the tests for the Death Note * feat: update testing exercises' solutions * feat: update lab08 exercises * untrack the gradle wrapper * improve the instructions * recover the wrapper --------- Co-authored-by: Danilo Pianini <[email protected]> Co-authored-by: Danilo Pianini <[email protected]>
- Loading branch information
1 parent
ac9a15d
commit dc42370
Showing
15 changed files
with
1,004 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,8 @@ | ||
# Unit testing with JUnit 5 | ||
|
||
Consider the *Banking* domain of previous labs: `AccountHolder`s, `BankAccount`s, and their implementations. | ||
Write unit tests to verify the correctness of these classes. | ||
|
||
Guidelines: | ||
1. Look at the class `TestSimpleBankAccount` that tests `SimpleBankAccount` implementation. | ||
2. Write tests described in class `TestStrictBankAccount` that tests `StrictBankAccount`. | ||
|
||
* For each class, test the construction of new instances (their initial state) | ||
* Test each method/behaviour works as expected | ||
* Consider "corner cases" - i.e. what might happen if the user passes "weird" inputs (e.g., a deposit of a negative value) | ||
* Use what your "learn" by preparing/running tests to improve the soundness of your implementations | ||
|
||
1. Write a test class `TestSimpleBankAccount` to test `SimpleBankAccount` | ||
2. Write a test class `TestStrictBankAccount` to test `StrictBankAccount` | ||
|
||
Notes: | ||
|
||
* Consult the [JavaDoc of JUnit 5](https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/api/package-summary.html) | ||
* For asserting equality on floats/doubles, consider using the overloaded method `assertEquals(double expected, double actual, double delta)` which allows you to specify a `delta` (tolerance) for equality | ||
* By the way, notice that the "standard" handling of floats/doubles (cf. IEEE 754) in programming languages is not a great choice for the management of bank accounts and financial transactions. It would be far better to use [`BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html). | ||
Notes: Consult the [JavaDoc of JUnit 5](https://junit.org/junit5/docs/5.0.1/api/org/junit/jupiter/api/package-summary.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
java/testing/junit/src/test/java/it/unibo/bank/impl/TestStrictBankAccount.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package it.unibo.bank.impl; | ||
|
||
import it.unibo.bank.api.AccountHolder; | ||
import it.unibo.bank.api.BankAccount; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static it.unibo.bank.impl.SimpleBankAccount.*; | ||
import static it.unibo.bank.impl.SimpleBankAccount.ATM_TRANSACTION_FEE; | ||
import static it.unibo.bank.impl.StrictBankAccount.TRANSACTION_FEE; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
public class TestStrictBankAccount { | ||
|
||
private final static int INITIAL_AMOUNT = 100; | ||
|
||
// 1. Create a new AccountHolder and a StrictBankAccount for it each time tests are executed. | ||
private AccountHolder mRossi; | ||
private BankAccount bankAccount; | ||
|
||
@BeforeEach | ||
public void setUp() { | ||
mRossi = new AccountHolder("Mario", "Rossi", 1); | ||
bankAccount = new StrictBankAccount(mRossi, 0.0); | ||
} | ||
|
||
// 2. Test the initial state of the StrictBankAccount | ||
@Test | ||
public void testInitialization() { | ||
assertEquals(0.0, bankAccount.getBalance()); | ||
assertEquals(0, bankAccount.getTransactionsCount()); | ||
assertEquals(mRossi, bankAccount.getAccountHolder()); | ||
} | ||
|
||
|
||
// 3. Perform a deposit of 100€, compute the management fees, and check that the balance is correctly reduced. | ||
@Test | ||
public void testManagementFees() { | ||
bankAccount.deposit(mRossi.getUserID(), INITIAL_AMOUNT); | ||
assertEquals(INITIAL_AMOUNT, bankAccount.getBalance()); | ||
bankAccount.chargeManagementFees(mRossi.getUserID()); | ||
assertEquals(INITIAL_AMOUNT - TRANSACTION_FEE - MANAGEMENT_FEE, bankAccount.getBalance()); | ||
} | ||
|
||
// 4. Test the withdraw of a negative value | ||
@Test | ||
public void testNegativeWithdraw() { | ||
try { | ||
bankAccount.withdraw(mRossi.getUserID(), -INITIAL_AMOUNT); | ||
} catch (IllegalArgumentException e) { | ||
assertNotNull(e.getMessage()); | ||
assertTrue(e.getMessage().length() > 1); | ||
} | ||
} | ||
|
||
// 4. Test withdrawing more money than it is in the account | ||
@Test | ||
public void testWithdrawingTooMuch() { | ||
try { | ||
bankAccount.withdraw(mRossi.getUserID(), INITIAL_AMOUNT); | ||
} catch (IllegalArgumentException e) { | ||
assertNotNull(e.getMessage()); | ||
assertTrue(e.getMessage().length() > 1); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Test-first | ||
|
||
Use the *Test-Driven Development (TDD)* methodology to develop the following. | ||
|
||
1. Observe the `DeathNote` interface, understand how it is supposed to work | ||
2. Create an implementation of `DeathNote` in which each method throws an Exception | ||
3. Write a test for the `DeathNote` implementation (the test will fail and that is okay) testing the following: | ||
1. Rule number 0 and negative rules do not exist in the DeathNote rules. | ||
* check that the exceptions are thrown correctly, that their type is the expected one, and that the message is not null, empty, or blank. | ||
2. No rule is empty or null in the DeathNote rules. | ||
* for all the valid rules, check that none is null or blank | ||
3. The human whose name is written in the DeathNote will eventually die. | ||
* verify that the human has not been written in the notebook yet | ||
* write the human in the notebook | ||
* verify that the human has been written in the notebook | ||
* verify that another human has not been written in the notebook | ||
* verify that the empty string has not been written in the notebook | ||
4. Only if the cause of death is written within the next 40 milliseconds of writing the person's name, it will happen. | ||
* check that writing a cause of death before writing a name throws the correct exception | ||
* write the name of a human in the notebook | ||
* verify that the cause of death is a heart attack | ||
* write the name of another human in the notebook | ||
* set the cause of death to "karting accident" | ||
* verify that the cause of death has been set correctly (returned true, and the cause is indeed "karting accident") | ||
* sleep for 100ms | ||
* try to change the cause of death | ||
* verify that the cause of death has not been changed | ||
5. Only if the cause of death is written within the next 6 seconds and 40 milliseconds of writing the death's details, it will happen. | ||
* check that writing the death details before writing a name throws the correct exception | ||
* write the name of a human in the notebook | ||
* verify that the details of the death are currently empty | ||
* set the details of the death to "ran for too long" | ||
* verify that death details have been set correctly (returned true, and the details are indeed "ran for too long") | ||
* write the name of another human in the notebook | ||
* sleep for 6100ms | ||
* try to change the details | ||
* verify that the details have not been changed | ||
4. Ask for a correction of the tests | ||
5. Verify that all tests fail | ||
6. Modify the implementation of the `DeathNote` in such a way that all tests work | ||
|
||
**Important notes**: | ||
* the current time measured as seconds since the Unix epoch is available as `System.currentTimeMillis()`. | ||
* the execution of a program can be paused for a given number of milliseconds using `Thread.sleep(long millis)`. |
Oops, something went wrong.