Dron Bhattacharya
02/21/2023, 3:05 PMclass Task(var title: String, bodyText: String = "") {
var body: String = bodyText
get() {
return if (this.body.isEmpty()) "NO BODY FOUND"
else this.body
}
fun printTask() {
println("Task: $title\n")
println("Body:")
println(body)
}
}
The current TaskTest.kt file:
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*
class TaskTest {
val testSample1: Task = Task("Learn Encapsulation")
val testSample2: Task = Task("Learn Encapsulation", "Encapsulation is good for reducing change")
@Test
fun printTask() {
}
}
Sam
02/21/2023, 3:06 PMprintln
is an example of a function that operates via side effects — i.e. it does something, instead of returning something.mkrussel
02/21/2023, 3:07 PMSystem.out
with your own object that builds a string.Dron Bhattacharya
02/21/2023, 3:09 PMmkrussel
02/21/2023, 3:12 PMSystem.out
which the println
function uses.
You then create a PrintStream
that takes an ByteArrayOutputStream
, you can then convert those bytes to a String to validate the printing.System.out
back to the original print stream.Sam
02/21/2023, 3:12 PMclass Task(var title: String, bodyText: String = "") {
var body: String = bodyText
get() {
return if (this.body.isEmpty()) "NO BODY FOUND"
else this.body
}
fun printTask() {
printer("Task: $title\n")
printer("Body:")
printer(body)
}
companion object {
var printer: (String) -> Unit = ::println
}
}
class TaskTest {
val testSample1: Task = Task("Learn Encapsulation")
val testSample2: Task = Task("Learn Encapsulation", "Encapsulation is good for reducing change")
@Test
fun printTask() {
val output = mutableListOf<String>()
Task.printer = { output.add(it) }
testSample1.printTask()
assertTrue(output.contains("Learn Encapsulation"))
}
}
(String) -> Unit
function than the whole system output stream.mkrussel
02/21/2023, 3:14 PMSam
02/21/2023, 3:14 PMAdam S
02/21/2023, 3:22 PMtypealias Logger = (String) -> Unit
So anywhere you want to print, pass in a Logger
typealias Logger = (String) -> Unit
class Task(
private val logger: Logger
) {
fun printTask() {
logger("Task: ...")
logger("Body: ...")
}
}
class Task(
private val logger: Logger = ::println
)
that uses a function reference to println()
, so for every message it will just print to stdoutfun main() {
// collect the log messages into this list
val logMessages = mutableListOf<String>()
// override the default logger
val task = Task(logger = logMessages::add)
task.printTask()
// now we can access all captured messages
println("captured messages $logMessages")
}
So that ^ will collect all your log messages into a list. Now each test can be run independently, and the logs won't be muddled up.Klitos Kyriacou
02/21/2023, 3:49 PMfield
. Otherwise this will cause an endless recursion and eventually a stack overflow:
var body: String = bodyText
get() {
return if (this.body.isEmpty()) "NO BODY FOUND"
else this.body
}
More details: https://kotlinlang.org/docs/properties.html#backing-fieldsTies
02/21/2023, 4:11 PMDron Bhattacharya
02/21/2023, 5:31 PMclass Task(var title: String, private val bodyText: String = "") {
var body: String = bodyText
get() = field.ifEmpty { "NO BODY FOUND" }
fun printTask(): String {
val text: String = """
Task: $title
Body:
$body
""".trimIndent().also {
println(it)
}
return text
}
}
TaskTest.kt:
class TaskTest {
val titles = listOf<String>("Learn Encapsulation", "Learn interface")
val bodys = listOf<String>("NO BODY FOUND", "Interface is good for reducing change")
val testSample1: Task = Task(titles[0])
val testSample2: Task = Task(titles[1], bodys[1])
@Test
fun printTask_NoBody() {
val expected =
"""
Task: ${titles[0]}
Body:
${bodys[0]}
""".trimIndent()
assertEquals(expected, testSample1.printTask())
}
@Test
fun printTask() {
val expected =
"""
Task: ${titles[1]}
Body:
${bodys[1]}
""".trimIndent()
assertEquals(expected, testSample2.printTask())
}
}
instance creation
of the class? I am new to thisprintTask()
function. But when I change the template, I have to change it manually in the test class too.
I have to change the template in 3 places. I know it can be better, but what to apply here is not clear to me (abstract class, interface, or something else).
Can I do anything here?import java.util.UUID
class Task(var title: String, bodyText: String = "") {
val id = UUID.randomUUID().hashCode()
var body: String = bodyText
get() = field.ifEmpty { "NO BODY FOUND" }
init {
println("Task created with ID=$id")
}
fun printTask() =
TaskPrintString(title, body).formattedString.also {
println(it)
}
}
data class TaskPrintString(private val title: String, private val body: String) {
val formattedString: String =
"""
--------------------
Task: $title
--------------------
Body:
$body
""".trimIndent()
}
TaskTest.kt:
class TaskTest {
val titles = listOf<String>("Learn Encapsulation", "Learn interface")
val bodys = listOf<String>("NO BODY FOUND", "Interface is good for reducing change")
@Test
fun printTask_NoBody() {
val testSample1: Task = Task(titles[0])
val expected = TaskPrintString(titles[0], bodys[0]).formattedString
assertEquals(expected, testSample1.printTask())
}
@Test
fun printTask_withBody() {
val testSample2: Task = Task(titles[1], bodys[1])
val expected = TaskPrintString(titles[1], bodys[1]).formattedString
assertEquals(expected, testSample2.printTask())
}
}