The input (that feeds a function) can be implemented in 2 ways: controlled by the caller or by the callee.
The outputs (that is provided by a function) can be implemented in 2 ways: exposed to the caller or by message.
The function's caller controls the input.
class Foo {
void foo(Object arg) {
...
}
}
class FooTest {
@Test
void test() {
foo("bar");
}
}
The function's callee controls the input.
class Foo {
void foo() {
Object arg = collaborator.get();
...
}
}
class FooTest {
@Test
void test() {
when(collaborator.get()).thenReturn("bar");
foo();
}
}
The output is exposed to the caller via a return value.
class Foo {
Object foo() {
return "bar";
}
}
class FooTest {
@Test
void test() {
Object actual = foo();
assertEquals("bar", actual);
}
}
The outputs are sent by message to some collaborators.
class Foo {
void foo() {
collaborator.set("bar");
}
}
class FooTest {
@Test
void test() {
foo();
verify(collaborator).set("bar");
}
}
class Archiver {
/**
* Delete if obsolete.
* A file is obsolete when its last modification is older than today.
*/
void clean(String path) {
LocalDate last = fileSystem.getLastModificationTime(path);
LocalDate now = clock.now();
if (isBefore(last, now)) {
fileSystem.delete(path);
}
}
}
class ArchiverTest {
@Test
void keep_recent_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("20/12/2017"));
when(clock.now()).thenReturn(new LocalDate("20/12/2017"));
// when
clean("/tmp/foo");
// then
verify(fileSystem, never()).delete(anyString());
}
@Test
void delete_old_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("19/12/2017"));
when(clock.now()).thenReturn(new LocalDate("20/12/2017"));
// when
clean("/tmp/foo");
// then
verify(fileSystem).delete("/tmp/foo");
}
}
class Archiver {
/**
* Delete if obsolete.
* A file is obsolete when its last modification is older than today.
*/
boolean clean(String path) {
LocalDate last = fileSystem.getLastModificationTime(path);
LocalDate now = clock.now();
if (isBefore(last, now)) {
return true;
}
return false;
}
}
class ArchiverTest {
@Test
void keep_recent_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("20/12/2017"));
when(clock.now()).thenReturn(new LocalDate("20/12/2017"));
// when
boolean actual = clean("/tmp/foo");
// then
assertFalse(actual);
}
@Test
void delete_old_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("19/12/2017"));
when(clock.now()).thenReturn(new LocalDate("20/12/2017"));
// when
boolean actual = clean("/tmp/foo");
// then
assertTrue(actual);
}
}
class Archiver {
/**
* Delete if obsolete.
* A file is obsolete when its last modification is older than today.
*/
void clean(String path, LocalDate now) {
LocalDate last = fileSystem.getLastModificationTime(path);
if (isBefore(last, now)) {
fileSystem.delete(path);
}
}
}
class ArchiverTest {
@Test
void keep_recent_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("20/12/2017"));
// when
clean("/tmp/foo", new LocalDate("20/12/2017"));
// then
verify(fileSystem, never()).delete(anyString());
}
@Test
void delete_old_file() {
// given
when(fileSystem.getLastModificationTime("/tmp/foo")).thenReturn(new LocalDate("19/12/2017"));
// when
clean("/tmp/foo", new LocalDate("20/12/2017"));
// then
verify(fileSystem).delete("/tmp/foo");
}
}
Readable article which reconciles simplicity and clarity !!! Good job @thieux