Is it possible to using Junit & kotlin with st...
# getting-started
p
Is it possible to using Junit & kotlin with stdin? Not mocking stdin, but interactively passing values myself?
r
Of course you could use
<http://System.in|System.in>
in your tests. Or alternatively pass some parameters in the run config. Generally, if you want a Unit test it's not advisable to rely on manual input. Better to read in a file or use a parameterized test.
đź’Ż 3
s
So if you check what System.in is, you see that it's a standard InputStream. So instead of hard-coding
<http://System.in|System.in>
you should write your code to use an InputStream and then confiugre that InputStream to be System.in, e.g. in Spring it would look like this:
Copy code
class MyClass(
    input: InputSteam,
) {
    fun whateverItIsYouDo() {
        // read from the input
        ...
    }
}

@Configuration
class BeanConfig {
    @Bean
    fun myClass() = MyClass(<http://System.in|System.in>)
}
because now you can use a different implementation on InputSteam in your tests:
Copy code
fun `whatever I do should work`() {
    val myClass = MyClass("my test input".byteInputStream())
    // execute the test
    val result = myClass.whateverItIsYouDo()
    // verify the result
    assertEquals(...)
}
of course maybe instead of adding the InputStream to the class you just pass it directly to the function as a parameter. whatever fits your case best. When working with InputStreams (or more precisely everything that implements Closeable as InputStream does) you should probably know about use. It makes sure that the InputStream is closed after you're done using it, so that you don't leak resources (the alternative would be to call
input.close()
manually). This is the equivalent of Java's try with resources. I found a good article covering it: https://www.baeldung.com/kotlin/inputstream-to-string
p
@Stephan Schröder I was relying on manual input rather than mokcing user input.
Of course you could use
<http://System.in|System.in>
in your tests.
Can't figure out how
Or alternatively pass some parameters in the run config.
Unfortunately I can't automate this part of testing. I've read that the
Test
task doesn't allow
stdin
.At best allows
stdout
just because it considers it as
Logging
. I was even thinking of starting to revert back to the
Application
plugin for the sole purpose of accepting manual
stdio
s
Do you want to route testdata over
<http://System.in|System.in>
in your tests (I don't think that's possible), or do you want to require manual user input (I don't think that's wise. Tests should be fully automatic). Hence my suggestion of only using
<http://System.in|System.in>
in your normal code, but indirectly through an InputStream variable, which you could then initilize with mock data InputStream in your test.
r
From my point of view, when you're relying on manual input, it's not a unit test any longer. Is there anything keeping you from using a
main
method instead of
@Test
?
p
Is tere anything keeping you from using a
main
method instead of
@Test
?
It's a networking logic with a remote service that's part of an Android project (Not even as a separate module). part of the
app
module.
do you want to require manual user input (I don't think that's wise.
I'm sure aware of that. Even tried to automate it, but unfortunately it needs manual intervention in my case.