I have a test class where I have to insert a specific topic. Whenever I try to insert it, it throws an error saying the topic already exists. This would be fine, however if I try to query that same topic within the test class, it returns 0 rows and so throws a QueryException. Any ideas on how to fix this or get around this error?

Here is a simple test class you can use to get the error. You must first ensure that the Topic exists within the org you are testing in:

private class TestTopicSample {
    static void testTopic() {
        Topic[] topics = [select Id from Topic where Name = 'Paused'];
        insert new Topic(Name = 'Paused');

Here is the error received running this:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, A topic with the name, Paused, already exists.: [Name]

1 Answer 1


First Understand about Test Data in Salesforce:-

Apex test data is transient and isn’t committed to the database. This means that after a test method finishes execution, the data inserted by the test doesn’t persist in the database. As a result, there is no need to delete any test data at the conclusion of a test. Likewise, all the changes to existing records, such as updates or deletions, don’t persist. This transient behavior of test data makes the management of data easier as you don’t have to perform any test data cleanup. At the same time, if your tests access organization data, this prevents accidental deletions or modifications to existing records.

By default, existing organization data isn’t visible to test methods, with the exception of certain setup objects. You should create test data for your test methods whenever possible. However, test code saved against Salesforce API version 23.0 or earlier has access to all data in the organization. Data visibility for tests is covered in more detail in the next section.

Topics names are unique in nature. You can not create two topics with same name.

In your case, when you are inserting topics, even if you have not annonated seealldata=true, Salesforce still check for the duplicate value in the database. It behave exactly same as group in Salesforce.

Also, Salesforce will only allow to query the record from its database when you have seealldata=true. Else you have to insert the record in test method.

If you have any dependecy with topic name in your class method to be tested, The best solution i can see is use seealldata=true here.Ideally it is not the best practise but i can see this particular case as why Salesforce allows you to query records from database.

  • Thanks - I ended up adding a fake topic specifically for test methods instead of the seeAllData=true. I have a utility class that makes sure that the real topic name is used in a non-test context.
    – willard
    Commented Nov 21, 2019 at 15:14
  • Also, Salesforce will only allow to query the record from its database when you have seealldata=true. - you should edit this - You can query certain data in testmethods without seeAllData=true, for example, User, Profile, StaticResource, etc. If Sobject is mockable, then testmethod should always create, even Users to provide best test isolation
    – cropredy
    Commented Nov 21, 2019 at 22:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .