I'm trying to create some Apex tests. Of course I am NOT using SeeAllData=true.

When I try to insert some instances of Product2, even though I've inserted none before, I get:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, A Product with this SKU already exists.: [StockKeepingUnit] Class.ProductBundleControllerIntTest: line 48, column 1

If I try the following just before the attempted insert:

        System.debug('######### EXISTING PRODUCT: ' + [
          SELECT Id, StockKeepingUnit 
          FROM Product2 
          WHERE StockKeepingUnit != NULL

I get:

17:58:23.557 (3561926690)|USER_DEBUG|[47]|DEBUG|######### EXISTING PRODUCT: ()

Even if I do the following to absolutely guarantee that no previous records could possibly exist and that I am inserting no duplicates, I get the same error:

        delete [
                SELECT Id, StockKeepingUnit
                FROM Product2
        Map<String, Product2> product2BySkuMap = new Map<String, Product2>();
        for (Product2 product2 : TEST_PRODUCT_LIST) {
            product2BySkuMap.put(product2.StockKeepingUnit, product2);
        insert product2BySkuMap.values();

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, A Product with this SKU already exists.: [StockKeepingUnit]

Further Notes:

  1. This is an absolutely fresh sandbox, so there really is no data for it to match or to avoid matching.

  2. Also at play within the functionality being tested are Custom Metadata which also needs to have values matching these SKU values. So even if we could change the SKU for the test, we can't (and shouldn't) change it for the Custom Metadata.

What could I be missing? How can I fix this?

  • @KrisGoncalves, Not really. 1. I am in a fresh sandbox which contains no data for it to otherwise match and 2. These values also need to match against Custom Metadata which can't (and shouldn't) be changed for the test. Oct 14, 2020 at 16:19
  • 4
    My fresh sandboxes come with product data which is why I believed it to be the same issue even with a fresh sandbox. If it is the issue, I don't disagree it's a bug/issue and leaves you in a bind. You'd have to look at mocking your SOQL against custom metadata to return different results that can rely on unique SKU product data or have specific records for just testing purposes denoted with an extra field Oct 14, 2020 at 16:34
  • If there is data, shouldn't selecting and deleting all the data either purge the data or throw an error? Anyway, I'd prefer not to change the target of these tests without having tests.... (Really, I want to refactor the hell out of the target, but that's a different issue.) Is there an existing bug report where I can say this effects me? Is workaround the only possible solution? Oct 14, 2020 at 16:45
  • 3
    I think the issue is that the test class is appropriately hiding the existing data when you query and execute a delete on it, but not when you're doing a dml for new objects. Ideally, it should be hidden for both situations. I tested in my sandbox and ran into the same issue but see no public known issue other than that question I linked Oct 14, 2020 at 17:35
  • Cheers for looking into it and giving feedback. Oct 15, 2020 at 8:08


Browse other questions tagged .