diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc
index f2ea02856c52b..4efb674bc5d7f 100644
--- a/content/services/auction_worklet/bidder_worklet_unittest.cc
+++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -40,6 +40,7 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/numeric/int128.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/interest_group/ad_auction_constants.h"
 #include "third_party/blink/public/common/interest_group/ad_auction_currencies.h"
@@ -352,6 +353,11 @@ class BidderWorkletTest : public testing::Test {
     data_version_.reset();
   }
 
+  // Because making a vector of move-only values is unwieldy, the test helpers
+  // take this variant that's easily constructible from a single bid object.
+  using OneOrManyBids = absl::variant<mojom::BidderWorkletBidPtr,
+                                      std::vector<mojom::BidderWorkletBidPtr>>;
+
   // Helper that creates and runs a script to validate that `expression`
   // evaluates to true when evaluated in a generateBid() script. Does this by
   // evaluating the expression in the content of generateBid() and throwing if
@@ -380,7 +386,7 @@ class BidderWorkletTest : public testing::Test {
   // to be the first returned bid.
   void RunGenerateBidWithReturnValueExpectingResult(
       const std::string& raw_return_value,
-      mojom::BidderWorkletBidPtr expected_bid,
+      OneOrManyBids expected_bids,
       const std::optional<uint32_t>& expected_data_version = std::nullopt,
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const std::optional<GURL>& expected_debug_loss_report_url = std::nullopt,
@@ -392,7 +398,7 @@ class BidderWorkletTest : public testing::Test {
       PrivateAggregationRequests expected_pa_requests = {},
       PrivateAggregationRequests expected_non_kanon_pa_requests = {}) {
     RunGenerateBidWithJavascriptExpectingResult(
-        CreateGenerateBidScript(raw_return_value), std::move(expected_bid),
+        CreateGenerateBidScript(raw_return_value), std::move(expected_bids),
         expected_data_version, expected_errors, expected_debug_loss_report_url,
         expected_debug_win_report_url, expected_set_priority,
         expected_update_priority_signals_overrides,
@@ -405,7 +411,7 @@ class BidderWorkletTest : public testing::Test {
   // first returned bid.
   void RunGenerateBidWithJavascriptExpectingResult(
       const std::string& javascript,
-      mojom::BidderWorkletBidPtr expected_bid,
+      OneOrManyBids expected_bids,
       const std::optional<uint32_t>& expected_data_version = std::nullopt,
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const std::optional<GURL>& expected_debug_loss_report_url = std::nullopt,
@@ -420,7 +426,7 @@ class BidderWorkletTest : public testing::Test {
     AddJavascriptResponse(&url_loader_factory_, interest_group_bidding_url_,
                           javascript);
     RunGenerateBidExpectingResult(
-        std::move(expected_bid), expected_data_version, expected_errors,
+        std::move(expected_bids), expected_data_version, expected_errors,
         expected_debug_loss_report_url, expected_debug_win_report_url,
         expected_set_priority, expected_update_priority_signals_overrides,
         std::move(expected_pa_requests),
@@ -434,7 +440,7 @@ class BidderWorkletTest : public testing::Test {
   // case the duration is expected to be at least `bid_duration` - useful for
   // testing that `bid_duration` at least seems to reflect timeouts.
   void RunGenerateBidExpectingResult(
-      mojom::BidderWorkletBidPtr expected_bid,
+      OneOrManyBids expected_bid_or_bids,
       const std::optional<uint32_t>& expected_data_version = std::nullopt,
       std::vector<std::string> expected_errors = std::vector<std::string>(),
       const std::optional<GURL>& expected_debug_loss_report_url = std::nullopt,
@@ -445,26 +451,41 @@ class BidderWorkletTest : public testing::Test {
               base::flat_map<std::string, std::optional<double>>(),
       PrivateAggregationRequests expected_pa_requests = {},
       PrivateAggregationRequests expected_non_kanon_pa_requests = {}) {
+    std::vector<mojom::BidderWorkletBidPtr> expected_bids;
+    if (absl::holds_alternative<mojom::BidderWorkletBidPtr>(
+            expected_bid_or_bids)) {
+      mojom::BidderWorkletBidPtr expected_bid =
+          absl::get<mojom::BidderWorkletBidPtr>(
+              std::move(expected_bid_or_bids));
+      if (expected_bid) {
+        expected_bids.push_back(std::move(expected_bid));
+      }
+    } else {
+      expected_bids = absl::get<std::vector<mojom::BidderWorkletBidPtr>>(
+          std::move(expected_bid_or_bids));
+    }
+
     auto bidder_worklet = CreateWorkletAndGenerateBid();
 
-    EXPECT_EQ(expected_bid.is_null(), bids_.empty());
-    if (expected_bid && !bids_.empty()) {
-      EXPECT_EQ(expected_bid->bid_role, bids_[0]->bid_role);
-      EXPECT_EQ(expected_bid->ad, bids_[0]->ad);
-      EXPECT_EQ(expected_bid->bid, bids_[0]->bid);
+    ASSERT_EQ(expected_bids.size(), bids_.size());
+    for (size_t i = 0; i < bids_.size(); ++i) {
+      const mojom::BidderWorkletBidPtr& expected_bid = expected_bids[i];
+      EXPECT_EQ(expected_bid->bid_role, bids_[i]->bid_role);
+      EXPECT_EQ(expected_bid->ad, bids_[i]->ad);
+      EXPECT_EQ(expected_bid->bid, bids_[i]->bid);
       EXPECT_EQ(blink::PrintableAdCurrency(expected_bid->bid_currency),
-                blink::PrintableAdCurrency(bids_[0]->bid_currency));
-      EXPECT_EQ(expected_bid->ad_descriptor.url, bids_[0]->ad_descriptor.url);
-      EXPECT_EQ(expected_bid->ad_descriptor.size, bids_[0]->ad_descriptor.size);
+                blink::PrintableAdCurrency(bids_[i]->bid_currency));
+      EXPECT_EQ(expected_bid->ad_descriptor.url, bids_[i]->ad_descriptor.url);
+      EXPECT_EQ(expected_bid->ad_descriptor.size, bids_[i]->ad_descriptor.size);
       if (!expected_bid->ad_component_descriptors) {
-        EXPECT_FALSE(bids_[0]->ad_component_descriptors);
+        EXPECT_FALSE(bids_[i]->ad_component_descriptors);
       } else {
-        EXPECT_THAT(*bids_[0]->ad_component_descriptors,
+        EXPECT_THAT(*bids_[i]->ad_component_descriptors,
                     ::testing::ElementsAreArray(
                         *expected_bid->ad_component_descriptors));
       }
       if (!expected_bid->bid_duration.is_zero()) {
-        EXPECT_GE(bids_[0]->bid_duration, expected_bid->bid_duration);
+        EXPECT_GE(bids_[i]->bid_duration, expected_bid->bid_duration);
       }
     }
     EXPECT_EQ(expected_data_version, data_version_);
@@ -2929,7 +2950,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetNumAdComponentsKAnon) {
   // With no k-anon enforcement, the requested 2 component ads are just the
   // first two component ads.
   RunGenerateBidWithReturnValueExpectingResult(kBid, non_k_anon_bid->Clone());
-  EXPECT_EQ(1u, bids_.size());
 
   // Turn on enforcement, but don't authorize anything. This is still going to
   // be a non-k-anon bid only; there will be an error-message from a failed
@@ -2941,7 +2961,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetNumAdComponentsKAnon) {
       /*expected_errors=*/
       {"https://url.test/ generateBid() bid render URL "
        "'https://response.test/' isn't one of the registered creative URLs."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Just authorizing the main bid still produces the same effect, but the
   // reason for re-run failure is different.
@@ -2957,7 +2976,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetNumAdComponentsKAnon) {
       {"https://url.test/ generateBid() bid adComponents URL "
        "'https://ad_component.test/' isn't one of the registered creative "
        "URLs."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Authorizing ad components 2 and 4, they should be used for k-anon bid but
   // there should still be the non-k-anon bid.
@@ -2970,20 +2988,21 @@ TEST_F(BidderWorkletMultiBidTest, TargetNumAdComponentsKAnon) {
           GURL("https://ad_component4.test/"))),
       true);
 
-  RunGenerateBidWithReturnValueExpectingResult(
-      kBid, mojom::BidderWorkletBid::New(
-                auction_worklet::mojom::BidRole::kEnforcedKAnon, "\"ad\"", 5,
-                /*bid_currency=*/std::nullopt,
-                /*ad_cost=*/std::nullopt,
-                blink::AdDescriptor(GURL("https://response.test/")),
-                /*ad_component_descriptors=*/
-                std::vector<blink::AdDescriptor>{
-                    blink::AdDescriptor(GURL("https://ad_component2.test/")),
-                    blink::AdDescriptor(GURL("https://ad_component4.test/"))},
-                /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-  ASSERT_EQ(2u, bids_.size());
-  bids_[1]->bid_duration = base::TimeDelta();
-  EXPECT_TRUE(bids_[1]->Equals(*non_k_anon_bid));
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(mojom::BidderWorkletBid::New(
+        auction_worklet::mojom::BidRole::kEnforcedKAnon, "\"ad\"", 5,
+        /*bid_currency=*/std::nullopt,
+        /*ad_cost=*/std::nullopt,
+        blink::AdDescriptor(GURL("https://response.test/")),
+        /*ad_component_descriptors=*/
+        std::vector<blink::AdDescriptor>{
+            blink::AdDescriptor(GURL("https://ad_component2.test/")),
+            blink::AdDescriptor(GURL("https://ad_component4.test/"))},
+        /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+    expected.push_back(non_k_anon_bid->Clone());
+    RunGenerateBidWithReturnValueExpectingResult(kBid, std::move(expected));
+  }
 
   // Authorizing 1 as well makes the bid suitable for both auctions.
   kanon_keys_.emplace(
@@ -3001,7 +3020,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetNumAdComponentsKAnon) {
                     blink::AdDescriptor(GURL("https://ad_component.test/")),
                     blink::AdDescriptor(GURL("https://ad_component2.test/"))},
                 /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-  EXPECT_EQ(1u, bids_.size());
 }
 
 TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
@@ -3042,7 +3060,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
   // With no k-anon enforcement, the requested 2 component ads are just the
   // first two component ads.
   RunGenerateBidWithReturnValueExpectingResult(kBid, non_k_anon_bid->Clone());
-  EXPECT_EQ(1u, bids_.size());
 
   // Turn on enforcement, but don't authorize anything. This is still going to
   // be a non-k-anon bid only; there will be an error-message from a failed
@@ -3054,7 +3071,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
       /*expected_errors=*/
       {"https://url.test/ generateBid() bid render URL "
        "'https://response.test/' isn't one of the registered creative URLs."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Just authorizing the main bid still produces the same effect, but the
   // reason for re-run failure is different.
@@ -3070,7 +3086,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
       {"https://url.test/ generateBid() bid adComponents URL "
        "'https://ad_component.test/' isn't one of the registered creative "
        "URLs."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Authorizing ad components 3 and 4 isn't enough since absence of 1 prevents
   // it from being accepted.
@@ -3089,27 +3104,27 @@ TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
       {"https://url.test/ generateBid() bid adComponents URL "
        "'https://ad_component.test/' isn't one of the registered creative "
        "URLs."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Now authorize 1 as well. Should get 1 and 3 as k-anon bid.
   kanon_keys_.emplace(
       auction_worklet::mojom::KAnonKey::New(
           blink::KAnonKeyForAdComponentBid(GURL("https://ad_component.test/"))),
       true);
-  RunGenerateBidWithReturnValueExpectingResult(
-      kBid, mojom::BidderWorkletBid::New(
-                auction_worklet::mojom::BidRole::kEnforcedKAnon, "\"ad\"", 5,
-                /*bid_currency=*/std::nullopt,
-                /*ad_cost=*/std::nullopt,
-                blink::AdDescriptor(GURL("https://response.test/")),
-                /*ad_component_descriptors=*/
-                std::vector<blink::AdDescriptor>{
-                    blink::AdDescriptor(GURL("https://ad_component.test/")),
-                    blink::AdDescriptor(GURL("https://ad_component3.test/"))},
-                /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-  ASSERT_EQ(2u, bids_.size());
-  bids_[1]->bid_duration = base::TimeDelta();
-  EXPECT_TRUE(bids_[1]->Equals(*non_k_anon_bid));
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(mojom::BidderWorkletBid::New(
+        auction_worklet::mojom::BidRole::kEnforcedKAnon, "\"ad\"", 5,
+        /*bid_currency=*/std::nullopt,
+        /*ad_cost=*/std::nullopt,
+        blink::AdDescriptor(GURL("https://response.test/")),
+        /*ad_component_descriptors=*/
+        std::vector<blink::AdDescriptor>{
+            blink::AdDescriptor(GURL("https://ad_component.test/")),
+            blink::AdDescriptor(GURL("https://ad_component3.test/"))},
+        /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+    expected.push_back(non_k_anon_bid->Clone());
+    RunGenerateBidWithReturnValueExpectingResult(kBid, std::move(expected));
+  }
 
   // Authorizing 2 as well makes the bid suitable for both auctions.
   kanon_keys_.emplace(
@@ -3127,7 +3142,6 @@ TEST_F(BidderWorkletMultiBidTest, TargetAndMandatoryAdComponentsKAnon) {
                     blink::AdDescriptor(GURL("https://ad_component.test/")),
                     blink::AdDescriptor(GURL("https://ad_component2.test/"))},
                 /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-  EXPECT_EQ(1u, bids_.size());
 }
 
 TEST_F(BidderWorkletMultiBidTest, GenerateBidMultiBid) {
@@ -3154,17 +3168,21 @@ TEST_F(BidderWorkletMultiBidTest, GenerateBidMultiBid) {
   EXPECT_EQ(reject_reason_, mojom::RejectReason::kNotAvailable);
 
   // Actually multiple bids.
-  RunGenerateBidWithReturnValueExpectingResult(
-      R"([{ad: "ad", bid: 2,
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(expected_bid->Clone());
+    expected.push_back(expected_bid->Clone());
+    expected[1]->bid = 3;
+    expected[1]->ad = "\"ad2\"";
+    RunGenerateBidWithReturnValueExpectingResult(
+        R"([{ad: "ad", bid: 2,
           render: "https://response.test/"},
           {ad: "ad2", bid: 3,
           render: "https://response.test/"},
          ])",
-      /*expected_bid=*/expected_bid->Clone());
-  ASSERT_EQ(2u, bids_.size());
-  EXPECT_EQ(bids_[1]->bid, 3);
-  EXPECT_EQ(bids_[1]->ad, "\"ad2\"");
-  EXPECT_EQ(reject_reason_, mojom::RejectReason::kNotAvailable);
+        std::move(expected));
+    EXPECT_EQ(reject_reason_, mojom::RejectReason::kNotAvailable);
+  }
 
   // Too many bids.
   RunGenerateBidWithReturnValueExpectingResult(
@@ -3334,22 +3352,26 @@ TEST_F(BidderWorkletMultiBidTest, SetBidMultiBid) {
       /*expected_bid=*/expected_bid->Clone(),
       /*expected_data_version=*/std::nullopt,
       /*expected_errors=*/{"https://url.test/:3 Uncaught boo."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Or two.
-  RunGenerateBidWithJavascriptExpectingResult(
-      R"(function generateBid() {
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(expected_bid->Clone());
+    expected.push_back(expected_bid->Clone());
+    expected[1]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response2.test"));
+    expected[1]->ad = "\"bad\"";
+    expected[1]->bid = 4;
+    RunGenerateBidWithJavascriptExpectingResult(
+        R"(function generateBid() {
          setBid([{ad: "ad", bid:2, render: "https://response.test"},
                  {ad: "bad", bid:4, render: "https://response2.test"}]);
          throw "boo";
        })",
-      /*expected_bid=*/expected_bid->Clone(),
-      /*expected_data_version=*/std::nullopt,
-      /*expected_errors=*/{"https://url.test/:4 Uncaught boo."});
-  ASSERT_EQ(2u, bids_.size());
-  EXPECT_EQ(bids_[1]->ad_descriptor,
-            blink::AdDescriptor(GURL("https://response2.test")));
-  EXPECT_EQ(bids_[1]->bid, 4);
+        std::move(expected),
+        /*expected_data_version=*/std::nullopt,
+        /*expected_errors=*/{"https://url.test/:4 Uncaught boo."});
+  }
 
   // ..but given our `multi_bid_limit_` is 2, not 3.
   RunGenerateBidWithJavascriptExpectingResult(
@@ -3375,7 +3397,6 @@ TEST_F(BidderWorkletMultiBidTest, SetBidMultiBid) {
       /*expected_bid=*/expected_bid3->Clone(),
       /*expected_data_version=*/std::nullopt,
       /*expected_errors=*/{"https://url.test/:5 Uncaught boo."});
-  EXPECT_EQ(1u, bids_.size());
 
   // Can overwrite with an empty array as well.
   RunGenerateBidWithJavascriptExpectingResult(
@@ -3415,7 +3436,6 @@ TEST_F(BidderWorkletMultiBidTest, SetBidMultiBid) {
       /*expected_bid=*/expected_bid3->Clone(),
       /*expected_data_version=*/std::nullopt,
       /*expected_errors=*/{"https://url.test/:8 Uncaught boo."});
-  EXPECT_EQ(1u, bids_.size());
 }
 
 // Make sure Date() is not available when running generateBid().
@@ -9824,7 +9844,6 @@ TEST_F(BidderWorkletTest, KAnonSimulate) {
   RunGenerateBidWithReturnValueExpectingResult(
       "",
       /*expected_bid=*/mojom::BidderWorkletBidPtr());
-  EXPECT_EQ(bids_.size(), 0u);
 
   // Sole bid is unauthorized. The non-enforced bid is there, kanon-bid isn't.
   // Since this is simulation mode, set_priority and errors should come from the
@@ -9845,7 +9864,6 @@ TEST_F(BidderWorkletTest, KAnonSimulate) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/11);
-  ASSERT_EQ(bids_.size(), 1u);
 
   // Now authorize it.
   kanon_keys_.emplace(
@@ -9869,7 +9887,6 @@ TEST_F(BidderWorkletTest, KAnonSimulate) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/11);
-  ASSERT_EQ(bids_.size(), 1u);
 
   // Add a second ad, not authorized yet, with script that it will try it
   // if it's in the ad vector.
@@ -9877,30 +9894,34 @@ TEST_F(BidderWorkletTest, KAnonSimulate) {
                                    /*metadata=*/std::nullopt);
   // Non-enforced bid will be 2. Since this is simulated mode, other things are
   // from the same run, so expected_set_priority is 12.
-  RunGenerateBidWithJavascriptExpectingResult(
-      CreateGenerateBidScript(
-          R"({ad: ["ad"], bid:interestGroup.ads.length,
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(mojom::BidderWorkletBid::New(
+        auction_worklet::mojom::BidRole::kUnenforcedKAnon, R"(["ad"])", 2,
+        /*bid_currency=*/std::nullopt,
+        /*ad_cost=*/std::nullopt,
+        blink::AdDescriptor(GURL("https://response2.test/")),
+        /*ad_component_descriptors=*/std::nullopt,
+        /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+    expected.push_back(expected[0]->Clone());
+    // k-anon-enforced bid will be 1.
+    expected[1]->bid_role = auction_worklet::mojom::BidRole::kEnforcedKAnon;
+    expected[1]->bid = 1;
+    expected[1]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response.test/"));
+
+    RunGenerateBidWithJavascriptExpectingResult(
+        CreateGenerateBidScript(
+            R"({ad: ["ad"], bid:interestGroup.ads.length,
           render:interestGroup.ads[interestGroup.ads.length - 1].renderURL})",
-          kSideEffectScript),
-      mojom::BidderWorkletBid::New(
-          auction_worklet::mojom::BidRole::kUnenforcedKAnon, R"(["ad"])", 2,
-          /*bid_currency=*/std::nullopt,
-          /*ad_cost=*/std::nullopt,
-          blink::AdDescriptor(GURL("https://response2.test/")),
-          /*ad_component_descriptors=*/std::nullopt,
-          /*modeling_signals=*/std::nullopt, base::TimeDelta()),
-      /*expected_data_version=*/std::nullopt,
-      /*expected_errors=*/{},
-      /*expected_debug_loss_report_url=*/std::nullopt,
-      /*expected_debug_win_report_url=*/std::nullopt,
-      /*expected_set_priority=*/12);
-  // k-anon-enforced bid will be 1.
-  ASSERT_EQ(bids_.size(), 2u);
-  EXPECT_EQ(bids_[1]->bid_role,
-            auction_worklet::mojom::BidRole::kEnforcedKAnon);
-  EXPECT_EQ(bids_[1]->ad, R"(["ad"])");
-  EXPECT_EQ(bids_[1]->bid, 1);
-  EXPECT_EQ(bids_[1]->ad_descriptor.url, GURL("https://response.test/"));
+            kSideEffectScript),
+        std::move(expected),
+        /*expected_data_version=*/std::nullopt,
+        /*expected_errors=*/{},
+        /*expected_debug_loss_report_url=*/std::nullopt,
+        /*expected_debug_win_report_url=*/std::nullopt,
+        /*expected_set_priority=*/12);
+  }
 
   // Authorize it.
   kanon_keys_.emplace(
@@ -9925,7 +9946,6 @@ TEST_F(BidderWorkletTest, KAnonSimulate) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/12);
-  ASSERT_EQ(bids_.size(), 1u);
 }
 
 TEST_F(BidderWorkletTest, KAnonEnforce) {
@@ -9939,7 +9959,6 @@ TEST_F(BidderWorkletTest, KAnonEnforce) {
   RunGenerateBidWithReturnValueExpectingResult(
       "",
       /*expected_bid=*/mojom::BidderWorkletBidPtr());
-  EXPECT_EQ(bids_.size(), 0u);
 
   // Sole bid is unauthorized. The non-enforced bid is there, kanon-bid isn't.
   // Since this is enforcement mode, set_priority and errors should come from
@@ -9963,7 +9982,6 @@ TEST_F(BidderWorkletTest, KAnonEnforce) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/10);
-  ASSERT_EQ(bids_.size(), 1u);
 
   // Now authorize it.
   kanon_keys_.emplace(
@@ -9987,38 +10005,41 @@ TEST_F(BidderWorkletTest, KAnonEnforce) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/11);
-  ASSERT_EQ(bids_.size(), 1u);
 
   // Add a second ad, not authorized yet, with script that it will try it
   // if it's in the ad vector.
   interest_group_ads_.emplace_back(GURL("https://response2.test/"),
                                    /*metadata=*/std::nullopt);
-  // Non-enforced bid will be 2. Since this is enforced mode, other things are
-  // from the restricted run, so expected_set_priority is 11.
+  // Non-enforced bid will be 2,  k-anon-enforced bid will be 1. Since this is
+  // enforced mode, other things are  from the restricted run, so
+  // expected_set_priority is 11.
+  std::vector<mojom::BidderWorkletBidPtr> expected;
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kUnenforcedKAnon, R"(["ad"])", 2,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response2.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kEnforcedKAnon, R"(["ad"])", 1,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+
   RunGenerateBidWithJavascriptExpectingResult(
       CreateGenerateBidScript(
           R"({ad: ["ad"], bid:interestGroup.ads.length,
           render:interestGroup.ads[interestGroup.ads.length - 1].renderURL})",
           kSideEffectScript),
-      mojom::BidderWorkletBid::New(
-          auction_worklet::mojom::BidRole::kUnenforcedKAnon, R"(["ad"])", 2,
-          /*bid_currency=*/std::nullopt,
-          /*ad_cost=*/std::nullopt,
-          blink::AdDescriptor(GURL("https://response2.test/")),
-          /*ad_component_descriptors=*/std::nullopt,
-          /*modeling_signals=*/std::nullopt, base::TimeDelta()),
+      std::move(expected),
       /*expected_data_version=*/std::nullopt,
       /*expected_errors=*/{},
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/11);
-  // k-anon-enforced bid will be 1.
-  ASSERT_EQ(bids_.size(), 2u);
-  EXPECT_EQ(bids_[1]->bid_role,
-            auction_worklet::mojom::BidRole::kEnforcedKAnon);
-  EXPECT_EQ(bids_[1]->ad, R"(["ad"])");
-  EXPECT_EQ(bids_[1]->bid, 1);
-  EXPECT_EQ(bids_[1]->ad_descriptor.url, GURL("https://response.test/"));
 
   // Authorize it.
   kanon_keys_.emplace(
@@ -10043,7 +10064,6 @@ TEST_F(BidderWorkletTest, KAnonEnforce) {
       /*expected_debug_loss_report_url=*/std::nullopt,
       /*expected_debug_win_report_url=*/std::nullopt,
       /*expected_set_priority=*/12);
-  ASSERT_EQ(bids_.size(), 1u);
 }
 
 // Test of multi-bid and k-anon: the bids are annotated with their roles
@@ -10074,21 +10094,27 @@ TEST_F(BidderWorkletMultiBidTest, KAnonClassify) {
 
   // 3 bids none of which are k-anon. This triggers a re-run, which errors out
   // as it returns the same thing.
-  RunGenerateBidWithJavascriptExpectingResult(
-      CreateGenerateBidScript(kBids), bid1.Clone(),
-      /*expected_data_version=*/std::nullopt,
-      /*expected_errors=*/
-      {"https://url.test/ generateBid() more bids provided than permitted by "
-       "auction configuration."});
-  ASSERT_EQ(3u, bids_.size());
-  EXPECT_EQ(bids_[1]->bid_role,
-            auction_worklet::mojom::BidRole::kUnenforcedKAnon);
-  EXPECT_EQ(bids_[1]->bid, 2);
-  EXPECT_EQ(bids_[1]->ad_descriptor.url, GURL("https://response2.test/"));
-  EXPECT_EQ(bids_[2]->bid_role,
-            auction_worklet::mojom::BidRole::kUnenforcedKAnon);
-  EXPECT_EQ(bids_[2]->bid, 3);
-  EXPECT_EQ(bids_[2]->ad_descriptor.url, GURL("https://response3.test/"));
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(bid1.Clone());
+    expected.push_back(bid1.Clone());
+    expected.push_back(bid1.Clone());
+    expected[1]->bid_role = auction_worklet::mojom::BidRole::kUnenforcedKAnon;
+    expected[1]->bid = 2;
+    expected[1]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response2.test/"));
+    expected[2]->bid_role = auction_worklet::mojom::BidRole::kUnenforcedKAnon;
+    expected[2]->bid = 3;
+    expected[2]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response3.test/"));
+
+    RunGenerateBidWithJavascriptExpectingResult(
+        CreateGenerateBidScript(kBids), std::move(expected),
+        /*expected_data_version=*/std::nullopt,
+        /*expected_errors=*/
+        {"https://url.test/ generateBid() more bids provided than permitted by "
+         "auction configuration."});
+  }
 
   // Authorize the second one. No re-run in this case since one ad is usable.
   kanon_keys_.emplace(
@@ -10096,17 +10122,22 @@ TEST_F(BidderWorkletMultiBidTest, KAnonClassify) {
           url::Origin::Create(interest_group_bidding_url_),
           interest_group_bidding_url_, GURL("https://response2.test/"))),
       true);
-  RunGenerateBidWithJavascriptExpectingResult(CreateGenerateBidScript(kBids),
-                                              bid1.Clone());
-  ASSERT_EQ(3u, bids_.size());
-  EXPECT_EQ(bids_[1]->bid_role,
-            auction_worklet::mojom::BidRole::kBothKAnonModes);
-  EXPECT_EQ(bids_[1]->bid, 2);
-  EXPECT_EQ(bids_[1]->ad_descriptor.url, GURL("https://response2.test/"));
-  EXPECT_EQ(bids_[2]->bid_role,
-            auction_worklet::mojom::BidRole::kUnenforcedKAnon);
-  EXPECT_EQ(bids_[2]->bid, 3);
-  EXPECT_EQ(bids_[2]->ad_descriptor.url, GURL("https://response3.test/"));
+  {
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(bid1.Clone());
+    expected.push_back(bid1.Clone());
+    expected.push_back(bid1.Clone());
+    expected[1]->bid_role = auction_worklet::mojom::BidRole::kBothKAnonModes;
+    expected[1]->bid = 2;
+    expected[1]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response2.test/"));
+    expected[2]->bid_role = auction_worklet::mojom::BidRole::kUnenforcedKAnon;
+    expected[2]->bid = 3;
+    expected[2]->ad_descriptor =
+        blink::AdDescriptor(GURL("https://response3.test/"));
+    RunGenerateBidWithJavascriptExpectingResult(CreateGenerateBidScript(kBids),
+                                                std::move(expected));
+  }
 }
 
 // Test for doing a re-run in multi-bid mode: returning only non-k-anon
@@ -10147,27 +10178,37 @@ TEST_F(BidderWorkletMultiBidTest, KAnonRerun) {
     }
   )";
 
-  RunGenerateBidWithJavascriptExpectingResult(
-      kScript, mojom::BidderWorkletBid::New(
-                   auction_worklet::mojom::BidRole::kUnenforcedKAnon, "null",
-                   10, /*bid_currency=*/std::nullopt,
-                   /*ad_cost=*/std::nullopt,
-                   blink::AdDescriptor(GURL("https://response.test/")),
-                   /*ad_component_descriptors=*/std::nullopt,
-                   /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-  ASSERT_EQ(4u, bids_.size());
-  EXPECT_EQ(bids_[1]->bid_role,
-            auction_worklet::mojom::BidRole::kUnenforcedKAnon);
-  EXPECT_EQ(bids_[1]->bid, 9);
-  EXPECT_EQ(bids_[1]->ad_descriptor.url, GURL("https://response2.test/"));
-  EXPECT_EQ(bids_[2]->bid_role,
-            auction_worklet::mojom::BidRole::kUnenforcedKAnon);
-  EXPECT_EQ(bids_[2]->bid, 8);
-  EXPECT_EQ(bids_[2]->ad_descriptor.url, GURL("https://response3.test/"));
-  EXPECT_EQ(bids_[3]->bid_role,
-            auction_worklet::mojom::BidRole::kEnforcedKAnon);
-  EXPECT_EQ(bids_[3]->bid, 7);
-  EXPECT_EQ(bids_[3]->ad_descriptor.url, GURL("https://response4.test/"));
+  std::vector<mojom::BidderWorkletBidPtr> expected;
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kUnenforcedKAnon, "null", 10,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kUnenforcedKAnon, "null", 9,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response2.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kUnenforcedKAnon, "null", 8,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response3.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+  expected.push_back(mojom::BidderWorkletBid::New(
+      auction_worklet::mojom::BidRole::kEnforcedKAnon, "null", 7,
+      /*bid_currency=*/std::nullopt,
+      /*ad_cost=*/std::nullopt,
+      blink::AdDescriptor(GURL("https://response4.test/")),
+      /*ad_component_descriptors=*/std::nullopt,
+      /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+
+  RunGenerateBidWithJavascriptExpectingResult(kScript, std::move(expected));
 }
 
 // Test for context re-use for k-anon rerun.
@@ -10197,20 +10238,22 @@ TEST_F(BidderWorkletTest, KAnonRerun) {
         blink::mojom::InterestGroup::ExecutionMode::kGroupedByOriginMode}) {
     execution_mode_ = execution_mode;
     SCOPED_TRACE(execution_mode_);
-    RunGenerateBidWithJavascriptExpectingResult(
-        kScript, mojom::BidderWorkletBid::New(
-                     auction_worklet::mojom::BidRole::kUnenforcedKAnon,
-                     R"(["ad"])", 1, /*bid_currency=*/std::nullopt,
-                     /*ad_cost=*/std::nullopt,
-                     blink::AdDescriptor(GURL("https://response2.test/")),
-                     /*ad_component_descriptors=*/std::nullopt,
-                     /*modeling_signals=*/std::nullopt, base::TimeDelta()));
-    ASSERT_EQ(2u, bids_.size());
-    EXPECT_EQ(bids_[1]->bid_role,
-              auction_worklet::mojom::BidRole::kEnforcedKAnon);
-    EXPECT_EQ(R"(["ad"])", bids_[1]->ad);
-    EXPECT_EQ(2, bids_[1]->bid);
-    EXPECT_EQ(GURL("https://response.test/"), bids_[1]->ad_descriptor.url);
+    std::vector<mojom::BidderWorkletBidPtr> expected;
+    expected.push_back(mojom::BidderWorkletBid::New(
+        auction_worklet::mojom::BidRole::kUnenforcedKAnon, R"(["ad"])", 1,
+        /*bid_currency=*/std::nullopt,
+        /*ad_cost=*/std::nullopt,
+        blink::AdDescriptor(GURL("https://response2.test/")),
+        /*ad_component_descriptors=*/std::nullopt,
+        /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+    expected.push_back(mojom::BidderWorkletBid::New(
+        auction_worklet::mojom::BidRole::kEnforcedKAnon, R"(["ad"])", 2,
+        /*bid_currency=*/std::nullopt,
+        /*ad_cost=*/std::nullopt,
+        blink::AdDescriptor(GURL("https://response.test/")),
+        /*ad_component_descriptors=*/std::nullopt,
+        /*modeling_signals=*/std::nullopt, base::TimeDelta()));
+    RunGenerateBidWithJavascriptExpectingResult(kScript, std::move(expected));
   }
 }