2

I have class:

@Service
public class A {

  @Value("${a.b.c}")
  private String abc;

  public void foo() {
   sout(abc);
  }
}

I Have test class:

@SpringBootTest
@SpringBootConfiguration
@RunWith(SpringRunner.class)
@TestPropertySource(locations = "classpath:application.yml")
public class TestA {

  @Value("${a.b.c}")
  private String abc;

  @InjectMocks
  private A a;

  @Test
  public void testFoo() {
    this.a.foo();
  }
}

When I debugging the test method testFoo(), I see that variable abc is read from the application.yml file. But, inside the foo() method, I see that the variable abc is null. How can I set variable abc such that it is available in method foo() when I trying to test this method?

DwB
  • 37,124
  • 11
  • 56
  • 82
Anton Kolosok
  • 482
  • 9
  • 24

2 Answers2

4

Step one is to answer this question: Am I unit testing the code in my class or am I integration testing the combination of Spring and some collection of code that includes my class?

If you are unit testing your code, then it is not necessary to have Spring do its thing. Instead, you only need to instantiate your class, set the values that Spring would have set for you, execute the method you are testing, then verify that your method executed correctly.

Here is your example unit test rewritten as I suggested:

public class TestA
{
  private static final String VALUE_ABC = "VALUE_ABC";

  private A classToTest;

  @Test
  public void testFoo()
  {
    classToTest.foo();
  }

  @Before
  public void preTestSetup()
  {
    classToTest = new A();

    ReflectionTestUtils.setField(
      classToTest,
      "abc",
      VALUE_ABC)
  }
}

Some Notes:

  1. ReflectionTestUtils is part of Spring-test.
  2. You don't need to use @InjectMocks because you have no mocks to inject.
  3. I don't know what sout is, so I excluded it from the test. You should verify that the sout method was called with the correct value (in this case VALUE_ABC).
  4. If you are just unit testing your code, you don't need Spring, which means that you don't need to use the @RunWith annotation.
DwB
  • 37,124
  • 11
  • 56
  • 82
0

You can try to overide the properties like that:

@TestPropertySource(locations = "location.properties",
  properties = "a.b.c=123")

Example taken from here

riorio
  • 6,500
  • 7
  • 47
  • 100