0

I use this in my MyService.kt.
The useXml is read via application.yml and application-test.yml

@Service
class MyService (
    @Value("\${something.use-xml}")
    var useXml: Boolean = false
) {

  if(useXml) {
    // do this
  } else {
    // do  that 
  }
....
}

this works as expected.

but for the testing I want to use both variation:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MyFunctionalTest {

    @Value("\${something.use-xml}")
        var useXml: Boolean = false

  //....
@ParameterizedTest
@ValueSource(booleans = [true,false])
fun `do a parameterized test`(useXML : Boolean) {
    useXml = useXML // this is (of course) not setting the variations for `MyService.kt`
    if (useXML) {
      // test this  
    } else {
      // test that
    } 
      
}

I want a possibility where I can set the variable for the application.yml file, so both variations are tested.

Is there any way of doing it?

3
  • 1
    Using parametrized test for true and false is ... very generous/lazy... :) Better would be (as i understand) to do one test (class) with "normal test" profile and another (nested!?) test (class), which also activates "test" profile, but overrides this special property!? -> @TestPtopertySource has (one of..second!) highest precedence (s) in spring boot props(13.) ..for some reason ;) Commented Oct 31, 2022 at 21:49
  • 1
    Simplest (and 3rd highest precedence(12.)): @SpringBootTest(properties={"foo=bar", "baz=buf",...}) ...@ActiveProfiles(...) Commented Oct 31, 2022 at 21:56
  • also a nice way of doing it... I will have a look! Commented Nov 1, 2022 at 11:14

1 Answer 1

1

Of course, it is possible. You need to inject the service that you are testing and set its useXml value. In your case, it'll look like this:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class MyServiceTest {

    @Autowired
    private lateinit var myService: MyService

    @ParameterizedTest
    @ValueSource(booleans = [true,false])
    fun `do a parameterized test`(useXML : Boolean) {
        myService.useXml = useXML // you have to set the value for the test case

        Assertions.assertEquals(useXML, myService.useXml)
    }
}

However, if I were you and have such a case, I'd go with two totally separate implementations of the same interface, if xml and the other format have something in common. In the end, you will have two classes (you need better naming for that):

  1. MyServiceXml
  2. MyServiceJson

Both this classes will be annotated will @ConditionalOnProperty("\${something.use-xml}") and they will be implementing the same interface.

That will be very easy to test, two different implementations, so two different test classes.

Sign up to request clarification or add additional context in comments.

1 Comment

OMG. how can I have not seen that I'm able to change the value after autowiring it. I have done that 100x before. but I was not aware, that I could control the set value. Thanks a lot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.