最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin2浏览0评论

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);
发布评论

评论列表(0)

  1. 暂无评论