You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于映射列表返回Iterator<Object[]>?附TestNG实现代码

Fixing TestNG DataProvider to Return Unique Map Entries

Let's break down the issue in your current code first, then walk through the fix to get the behavior you want.

The Problem with Your Current Code

Your existing code creates one single HashMap instance outside the for loop. Every iteration just updates the same map's values and adds it to the list. Since you're adding a reference to the same map each time, all entries in listings end up pointing to the final state of that single map. If you uncomment listing.clear(), all entries would become empty maps entirely—definitely not what you want.

The Fix: Create a New Map Per Iteration

To get three distinct maps (each with its own category, usage, and country values), you need to instantiate a new HashMap inside the for loop. This ensures every entry in your list is an independent object.

Here's the corrected code that returns an Iterator<Object[]> as you requested:

@DataProvider(name = "NewListings") 
public Iterator<Object[]> AddNewListings(){
    List<Map<String,String>> listings = new ArrayList<>();
    Random rand = new Random();
    
    // Create a new Map for each iteration
    for (int i = 0; i < 3; i++){
        Map<String,String> listing = new HashMap<>();
        listing.put("category", Integer.toString(rand.nextInt(8) + 1));
        listing.put("usage", Integer.toString(rand.nextInt(8) + 1));
        listing.put("country", Integer.toString(rand.nextInt(8) + 1));
        listings.add(listing); 
    }
    
    // Convert the list of maps to an Iterator<Object[]> using streams (cleaner than loops)
    return listings.stream()
                   .map(map -> new Object[]{map})
                   .iterator();
}

@Test(dataProvider = "NewListings") 
public void addListing(Map<String, String> field){
    // Now each test run gets a unique map with all three fields
    // Example usage:
    System.out.println("Category: " + field.get("category"));
    System.out.println("Usage: " + field.get("usage"));
    System.out.println("Country: " + field.get("country"));
    // do your actual test logic here
}

If You Prefer Returning Object[][] Instead

TestNG also accepts Object[][] as a DataProvider return type. Here's how to adjust the code for that:

@DataProvider(name = "NewListings") 
public Object[][] AddNewListings(){
    List<Map<String,String>> listings = new ArrayList<>();
    Random rand = new Random();
    
    for (int i = 0; i < 3; i++){
        Map<String,String> listing = new HashMap<>();
        listing.put("category", Integer.toString(rand.nextInt(8) + 1));
        listing.put("usage", Integer.toString(rand.nextInt(8) + 1));
        listing.put("country", Integer.toString(rand.nextInt(8) + 1));
        listings.add(listing); 
    }
    
    // Convert list to Object[][] using streams
    return listings.stream()
                   .map(map -> new Object[]{map})
                   .toArray(Object[][]::new);
}

Key Takeaways

  • Always create a new data object (in this case, a HashMap) inside your loop when building test data—this prevents reference sharing and data overwrites.
  • TestNG supports both Iterator<Object[]> and Object[][] for DataProviders; pick whichever fits your code style better.
  • Java Streams make converting collections to the required DataProvider format much cleaner than manual loops.

内容的提问来源于stack exchange,提问作者gmitsios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:47:48