[SalesForce] Can’t Insert CollaborationGroup in Test Class

I've got a Trigger that will automatically add newly created Users to our companies main chatter group. It works as expected, but the test class is failing for some strange reason!

When I try to insert a new CollaborationGroup like below:

CollaborationGroup cg = new CollaborationGroup(
  Name = 'New Group',
  CollaborationType = 'Private'
);

INSERT cg;

… And query for that Id like below:

Id theChatterGroup = [SELECT Id FROM CollaborationGroup WHERE Name = 'New Group' LIMIT 1].Id;

I get the following error:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, An active or archived group with this name already exists or is being deleted. Choose a different name or try again in a few minutes.: [Name]

So I figured "okay, maybe CollaborationGroups are like profiles or something and don't need to be created in test classes?". But when I remove that insert, I get this error…

System.QueryException: List has no rows for assignment to SObject

… When I'm querying for the Id of the Chatter Group.

I feel like I'm missing something obvious here. Can anyone guide me in the right direction?

Edit
The group exists in both production and I created it in the Sandbox. When we refreshed the sandbox, we didn't migrate and Chatter data.

Edit 2
I've tried checking if it exists, but still getting the same errors.

Integer cgExists = [SELECT Count() FROM CollaborationGroup WHERE Name = 'My Group'];

if (cgExists == 0) {
  CollaborationGroup cg = new CollaborationGroup(
    Name = 'My Group',
    CollaborationType = 'Private'
  );

  INSERT cg;
}

Best Answer

I ran into this same issue recently. In my case, I was trying to create multiple Chatter groups as a part of our Sandbox Refresh Script. Turns out existing CollaborationGroups are not visible during a test, but they are still evaluated for the unique group name requirement.

Using the @IsTest(SeeAllData=true) annotation for your test method will allow you to check if the group already exists; then you can either create a new group or interact with the existing group.

Class for creating Chatter groups

private static void createChatterGroups(List<String> grpNames){
    //Map existing Chatter groups that match list of group names
    Map<String, CollaborationGroup> grpMap = new Map<String, CollaborationGroup>();
    for (CollaborationGroup cg : [SELECT Name FROM CollaborationGroup WHERE Name IN :grpNames]) {
        grpMap.put(cg.Name, cg);
    }
    //Create Public Chatter groups
    List<CollaborationGroup> grps = new List<CollaborationGroup>();
    for (String grpName:grpNames) {
        //Confirm group does not already exist
        if (!grpMap.containsKey(grpName)) {
            CollaborationGroup g = new CollaborationGroup(Name=grpName, CollaborationType='Public');
            grps.add(g);
        }
    }
    insert grps;
}

Test class

@isTest(SeeAllData=true)
static void createChatterGroupTest() { 
    List<String> grpNames = new List<String> {'Group1','Group2'};

    Test.startTest();
    createChatterGroups(grpNames);
    Test.stopTest();

    //Validate that Chatter groups exist
    Map<String, CollaborationGroup> grpMap = new Map<String, CollaborationGroup>();
    for (CollaborationGroup cg : [SELECT Name FROM CollaborationGroup]) {
        grpMap.put(cg.Name, cg);
    }
    for (String grpName:grpNames) {
        system.assert(grpMap.containsKey(grpName), grpName + ' Chatter group was not created');
    }
}