java - Mocking Spring-Vault VaultResponse in Spring boot application always returns null object - Stack Overflow

I have implemented Spring Security in my Spring boot application and I am retrieving user credentials f

I have implemented Spring Security in my Spring boot application and I am retrieving user credentials from Hashicorp vault . I am able to connect to HashiCorp vault using Spring Vault's vault template and receiving a vault response successfully. Here is how the response looks like (its an array of hashmaps)

 //VaultResponse output structure
 [

data: {

password: someVal,

username: user,

db.password: somePass,

db.username: user

},

metadata: {

created_time: 2025-01-01,

custom_metadata: null,

detection_time: ,

destroyed: false,

version: 7

}

]

I have created hashmap of the exact dataset and added to an arraylist and expect this data to be returned when mocking VaultResponse but instead VaultReponse.data is always coming back as null.

@Test
public void loadUserByUsername_TestSuccess() 
{
   VaultResponse mockResponse = Mockito.mock(VaultResponse.class);       

   Map<String, Object> dataMap = new HashMap<>();
   dataMap.put("password", "someVal");
   dataMap.put("username", "user");
   dataMap.put("db.password", "somePass");
   dataMap.put("db.username", "user");

    // Create the nested 'metadata' map
    Map<String, Object> metadataMap = new HashMap<>();
    metadataMap.put("created_time", "2025-01-01");
    metadataMap.put("custom_metadata", null);
    metadataMap.put("detection_time", "");
    metadataMap.put("destroyed", false);
    metadataMap.put("version", 7);

    // Create a List to hold the dataMap and metadataMap
    List<Map<String, Object>> responseList = new ArrayList<>();
    responseList.add(dataMap);
    responseList.add(metadataMap);

    //**VaultResponse.data is always coming back as null**
    when(mockResponse.getData()).thenReturn(responseList);

'''

Edit: Adding service class implemenation

My service class implement's Spring Security's User's interface. The method specifically being tested is :

    public class UserServiceClass
   {
     public UserDetails loadUserByUsername(String 
      username) throws UsernameNotFoundException{

     //VaultTemplate bean is injected using 
     @Autowired

     VaultResponse response =vaulTemplate.read(path);

    if(response != null &&  response.getData != null) 
    {
    
      Map<String,Object> vaultData = 
     response.getData();

     //Traverse through vaultData, and extract 
    username and password

      if(password == null or username == null){
      throw new UsernameNotFoundException("User not 
     found");
      } //end if 

      return new User(username,password);
      }
       } //end method
        } //end class

       //My test implementation
       public class UserServiceclassTest{

      @Mock
      UserDetails userDetails;

     @Mock
     VaultTemplate vaultTemplate;

   @InjectMock
   UserServiceClass userServiceClass

   VaultResponse mockResponse = 
    Mockito.mock(VaultResponse.class);       

      Map<String, Object> dataMap = new HashMap<> ();
        dataMap.put("password", "someVal");
        dataMap.put("username", "user");
        dataMap.put("db.password", "somePass");
        dataMap.put("db.username", "user");

        // Create the nested 'metadata' map
        Map<String, Object> metadataMap = new 
        HashMap<>();
        metadataMap.put("created_time", "2025-0101");
        metadataMap.put("custom_metadata", null);
        metadataMap.put("detection_time", "");
        metadataMap.put("destroyed", false);
        metadataMap.put("version", 7);

        // Create a List to hold the dataMap and 
        metadataMap
        List<Map<String, Object>> responseList = new 
        ArrayList<>();
        responseList.add(dataMap);
        responseList.add(metadataMap);

       public void loadUserByUsername() {

  when(mockResponse.getData()).thenReturn(responseList);

   **//Here mockResponse is throwing null exception**
when(vaultTemplate.read(path)).thenReturn(mockResponse);

  //Traverse through data to get username and pass it to 
   function being called
   UserDetails userDetails = 
   userServiceClass.loadUserByUsername(username);

   //Assertions

   }
   }

Issue: What am I doing wrong here? How can I mock VaultResponse.class to return the needed response structure?

Thank you

I have implemented Spring Security in my Spring boot application and I am retrieving user credentials from Hashicorp vault . I am able to connect to HashiCorp vault using Spring Vault's vault template and receiving a vault response successfully. Here is how the response looks like (its an array of hashmaps)

 //VaultResponse output structure
 [

data: {

password: someVal,

username: user,

db.password: somePass,

db.username: user

},

metadata: {

created_time: 2025-01-01,

custom_metadata: null,

detection_time: ,

destroyed: false,

version: 7

}

]

I have created hashmap of the exact dataset and added to an arraylist and expect this data to be returned when mocking VaultResponse but instead VaultReponse.data is always coming back as null.

@Test
public void loadUserByUsername_TestSuccess() 
{
   VaultResponse mockResponse = Mockito.mock(VaultResponse.class);       

   Map<String, Object> dataMap = new HashMap<>();
   dataMap.put("password", "someVal");
   dataMap.put("username", "user");
   dataMap.put("db.password", "somePass");
   dataMap.put("db.username", "user");

    // Create the nested 'metadata' map
    Map<String, Object> metadataMap = new HashMap<>();
    metadataMap.put("created_time", "2025-01-01");
    metadataMap.put("custom_metadata", null);
    metadataMap.put("detection_time", "");
    metadataMap.put("destroyed", false);
    metadataMap.put("version", 7);

    // Create a List to hold the dataMap and metadataMap
    List<Map<String, Object>> responseList = new ArrayList<>();
    responseList.add(dataMap);
    responseList.add(metadataMap);

    //**VaultResponse.data is always coming back as null**
    when(mockResponse.getData()).thenReturn(responseList);

'''

Edit: Adding service class implemenation

My service class implement's Spring Security's User's interface. The method specifically being tested is :

    public class UserServiceClass
   {
     public UserDetails loadUserByUsername(String 
      username) throws UsernameNotFoundException{

     //VaultTemplate bean is injected using 
     @Autowired

     VaultResponse response =vaulTemplate.read(path);

    if(response != null &&  response.getData != null) 
    {
    
      Map<String,Object> vaultData = 
     response.getData();

     //Traverse through vaultData, and extract 
    username and password

      if(password == null or username == null){
      throw new UsernameNotFoundException("User not 
     found");
      } //end if 

      return new User(username,password);
      }
       } //end method
        } //end class

       //My test implementation
       public class UserServiceclassTest{

      @Mock
      UserDetails userDetails;

     @Mock
     VaultTemplate vaultTemplate;

   @InjectMock
   UserServiceClass userServiceClass

   VaultResponse mockResponse = 
    Mockito.mock(VaultResponse.class);       

      Map<String, Object> dataMap = new HashMap<> ();
        dataMap.put("password", "someVal");
        dataMap.put("username", "user");
        dataMap.put("db.password", "somePass");
        dataMap.put("db.username", "user");

        // Create the nested 'metadata' map
        Map<String, Object> metadataMap = new 
        HashMap<>();
        metadataMap.put("created_time", "2025-0101");
        metadataMap.put("custom_metadata", null);
        metadataMap.put("detection_time", "");
        metadataMap.put("destroyed", false);
        metadataMap.put("version", 7);

        // Create a List to hold the dataMap and 
        metadataMap
        List<Map<String, Object>> responseList = new 
        ArrayList<>();
        responseList.add(dataMap);
        responseList.add(metadataMap);

       public void loadUserByUsername() {

  when(mockResponse.getData()).thenReturn(responseList);

   **//Here mockResponse is throwing null exception**
when(vaultTemplate.read(path)).thenReturn(mockResponse);

  //Traverse through data to get username and pass it to 
   function being called
   UserDetails userDetails = 
   userServiceClass.loadUserByUsername(username);

   //Assertions

   }
   }

Issue: What am I doing wrong here? How can I mock VaultResponse.class to return the needed response structure?

Thank you

Share Improve this question edited Mar 17 at 3:00 user1462617 asked Mar 16 at 15:02 user1462617user1462617 4232 gold badges14 silver badges24 bronze badges 6
  • 1 pls share the code under test, and full test method. Now in test method you re not calling any logic to test – Geii Lvov Commented Mar 16 at 16:20
  • How do you inject your VaultResponse dependency into your service? Note that Mockito can only mock methods, so even if you mock getData() to return a value, data (the field) would still show the original value (e.g. null) in a debugger. – knittl Commented Mar 16 at 18:25
  • This question is similar to: Why are my mocked methods not called when executing a unit test?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – knittl Commented Mar 16 at 18:26
  • @Gergii Lvov please see my Edits , I have added my implementation . Thank you – user1462617 Commented Mar 17 at 3:02
  • 1 The edit is completely unreadable. Please format your code properly. If this is indeed your full test code, you are never initializing the mocks. You are either missing the annotation to use the Mockito extension or the initMocks/openMocks call (only use one, they must not be used both). Without that, your @Mock annotations don't have any effect: it's not mockResponse that is throwing an NPE, but vaultTemplate.read(…), because the field is still null (never initialized). Look at "Corollary: Object life cycles and magic framework annotations" in the linked duplicate. – knittl Commented Mar 17 at 8:49
 |  Show 1 more comment

1 Answer 1

Reset to default -1

Resolved the issue by replacing Autowired bean creation of VaultTemplate with manually creating a new instance. of VaultTemplate.

VaultTemplate vaultTemplate = new VaultTemplate(VaultEndpoint vaultEndpoint, ClientAuthentication clientAuthentication);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744596442a4582918.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信