title: How do I test my CustomUserDetailsService?
body: <p>I have a <code>CustomerUserDetailsService</code> class, which is part of an implementation of Spring Boot authentication. I have tested my code manually, and it works correctly, allowing me to successfully log in to my app. However, I am unable to work out how to test the <code>CustomerUserDetailsService</code>.</p>
  <p>As a unit test, I believe I would need to mock the <code>userRepository</code> member variable, but whatever I try in my test fails, the reason being <code>userRepository</code> is set to <code>null</code>. I've tried adding the <code>@Repository</code> annotation to <code>userRepository</code> but am told that is not allowed because it is an interface. There's also the fact that <code>loadUserByUsername</code> returns an instance of <code>CustomUserDetails</code>, which is just an implementation of an interface, so I have no idea how I'd mock that dependency?</p>
  <p>I've also tried doing some kind of integration test but had similar issues, probably due to incorrect annotations on the test itself. In an ideal world, I'd prefer a unit test and would be extremely grateful for any guidance as to how to set it up.</p>
  <p>These are the relevant classes...</p>
  <p><strong>CustomerUserDetailsService:</strong></p>
  <pre class="lang-java prettyprint-override"><code>package com.phil.urlshortener.security;
  
  import com.phil.urlshortener.model.User;
  import com.phil.urlshortener.repositories.UserRepository;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.security.core.userdetails.UserDetailsService;
  import org.springframework.security.core.userdetails.UsernameNotFoundException;
  
  public class CustomUserDetailsService implements UserDetailsService {
    @Autowired private UserRepository userRepository;
  
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      User user = userRepository.findByUsername(username);
  
      if (user == null) {
        throw new UsernameNotFoundException(&quot;User not found&quot;);
      }
  
      return new CustomUserDetails(user);
    }
  }
  </code></pre>
  <p><strong>User:</strong></p>
  <pre class="lang-java prettyprint-override"><code>package com.phil.urlshortener.model;
  
  import lombok.Data;
  
  import javax.persistence.*;
  
  @Data
  @Entity
  public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
  
    @Column(nullable = false, unique = true, length = 50)
    private String username;
  
    @Column(nullable = false, length = 64)
    private String password;
  }
  </code></pre>
  <p><strong>UserRepository:</strong></p>
  <pre class="lang-java prettyprint-override"><code>package com.phil.urlshortener.repositories;
  
  import com.phil.urlshortener.model.User;
  import org.springframework.data.jpa.repository.Query;
  import org.springframework.data.repository.CrudRepository;
  
  public interface UserRepository extends CrudRepository&lt;User, Long&gt; {
    @Query(&quot;SELECT u FROM User u WHERE u.username = ?1&quot;)
    User findByUsername(String username);
  }
  </code></pre>
  <p><strong>CustomUserDetails:</strong></p>
  <pre class="lang-java prettyprint-override"><code>package com.phil.urlshortener.security;
  
  import com.phil.urlshortener.model.User;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.userdetails.UserDetails;
  
  import java.util.Collection;
  
  public class CustomUserDetails implements UserDetails {
    private final User user;
  
    public CustomUserDetails(User user) {
      this.user = user;
    }
  
    @Override
    public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {
      return null;
    }
  
    @Override
    public String getPassword() {
      return user.getPassword();
    }
  
    @Override
    public String getUsername() {
      return user.getUsername();
    }
  
    @Override
    public boolean isAccountNonExpired() {
      return true;
    }
  
    @Override
    public boolean isAccountNonLocked() {
      return true;
    }
  
    @Override
    public boolean isCredentialsNonExpired() {
      return true;
    }
  
    @Override
    public boolean isEnabled() {
      return true;
    }
  }
  </code></pre>