title: JUnit 5/Spring Boot - Use Properties but Mock Dependencies
body: <p>I'm trying to write unit tests for a DAO/Repository. My intent is to mock the <code>NamedParameterJdbcTemplate</code> object within and verify that the surrounding business logic doesn't do any bad (i.e.: handles nulls, etc...).</p>
  <p>I'd also like to verify that the SQL is combined correctly. I can do this with <code>doAnswer(...)</code>, but the SQL queries live in a <code>.properties</code> file.</p>
  <p>Is there a way to load a <code>.properties</code> file for testing, without loading all of the other dependencies of this class?</p>
  <h2>What I've Tried</h2>
  <p>I've tried decorating the Test class with various permutations of :</p>
  <pre class="lang-java prettyprint-override"><code>@ExtendWith(SpringExtension.class)
  @ExtendWith(MockitoExtension.class)
  @ContextConfiguration(classes = WidgetRepositoryImpl.class)
  @TestPropertySource(properties = &quot;sql.properties&quot;)
  </code></pre>
  <p>However, turning these on and off always seems to have one of the following effects:</p>
  <ul>
  <li>Load the <code>NamedParameterJdbcTemplate</code> as a bean. This <em>could</em> work if I specified the nearby <code>AppConfig</code> class in the <code>ContextConfiguration</code> annotation, but then I'd need to load <em>all</em> of its underlying dependencies, and the whole point is to <em>mock</em> this field.</li>
  <li>Load the Repository and mock the <code>NamedParameterJdbcTemplate</code>, but not load <code>sql.properties</code>. The SQL statements are now null.</li>
  </ul>
  <p>I want to avoid <code>ReflectionTestUtils.setField(widgetRepository, &quot;namedParameterJdbcTemplate&quot;, &quot;&lt;put the sql here&gt;&quot;)</code>. This works, but there are many SQL queries (the code below is very simplified). It also introduces a risk of human error (since now we're testing strings in the Test class, not the actual properties file.</p>
  <h2>The question</h2>
  <p><strong>Is there any way to load <code>sql.properties</code> for this class, but not attempt to load the NamedParameterJdbcTemplate?</strong></p>
  <h3>Unit Test</h3>
  <pre class="lang-java prettyprint-override"><code>@ExtendWith(SpringExtension.class)
  @TestPropertySource(properties = &quot;sql.properties&quot;)
  class WidgetRepositoryImplTest  {
  
    @Mock
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
  
    @Autowired
    private WidgetRepository widgetRepository;
  
    @Test
    public void testGetWidgetById() {
      // build a mock that returns a fake widget, and stores the SQL string for other tests
      doAnswer(invocation -&gt; { ...omitted for brevity... }).when(namedParameterJdbcTemplate).query(anyString(), anyMap(), any(WidgetMapper.class));
      Widget widget = widgetRepository.getWidgetById(&quot;asdf-1234&quot;);
      assertNotNull(widget);
    }
  </code></pre>
  <h3>Repository</h3>
  <pre class="lang-java prettyprint-override"><code>@PropertySource(&quot;classpath:sql.properties&quot;)
  @Slf4j
  @Repository
  public class WidgetRepositoryImpl implements WidgetRepository {
  
    @Value(&quot;${widget-sql.selects.select-widget-by-id}&quot;)
    private String selectWidgetByIdQuery;
  
    @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
  
    @Override
    public Widget getWidgetById(String id) {
      Map&lt;String, String&gt; params =  new HashMap&lt;&gt;();
      params.put(&quot;widgetId&quot;, id);
      List&lt;Widget&gt; results = namedParameterJdbcTemplate.query(selectWidgetByIdQuery, params, new WidgetMapper());
  
      if (results.isEmpty()) {
        return null;
      }
  
      return results.get(0);
    }
  </code></pre>
  <h3>sql.properties</h3>
  <pre><code>widget-sql.selects.select-widget-by-id=select * from [WIDGETS] where WIDGET_ID=:widgetId
  # a few dozen additional queries in here
  </code></pre>