According to this Salesforce guide and this forum answer, viewstat record will be created if we use UPDATE VIEWSTAT clause at the end of the query. However its not working as expected in my Test Class.

Below is the code I am working on.

Customer_Facing_Popup__kav newArticle2 = new Customer_Facing_Popup__kav(Title='test article2', UrlName='testarticleur2', Language='en_US',IsVisibleInPkb = True);  
insert newArticle2; 
List<Customer_Facing_Popup__kav> dummyList = [SELECT Title FROM Customer_Facing_Popup__kav WHERE Language = 'en_US' AND ID = :newArticle2.Id UPDATE VIEWSTAT]; //Should create ViewStat records. 
System.debug([SELECT parentId, viewCount, channel FROM Customer_facing_popup__viewstat]); //Returning zero records

Any pointers on how to create ViewStat records in test class?

  • Have you tried it with Test.stopTest?
    – Adrian Larson
    Commented Dec 26, 2017 at 6:52
  • Yes, I thought it might be asynchronous, but Test.stopTest is not helping. Commented Dec 26, 2017 at 7:13

2 Answers 2


This is probably covered as a known limitation of unit testing. As mentioned in Isolation of Test Data from Organization Data in Unit Tests:

There might be some cases where you can’t create certain types of data from your test method because of specific limitations ... Records that are created only after related records are committed to the database ...

I would speculate that since things like "tracked changes" and the like can't be created in unit tests, it would make sense that you also couldn't create/update a view stat in a unit test, either.

Some basic testing shows that view stats aren't even updated in real time. I tried several live tests and found that the view stats are updated at some later point after the actual view occurs.

I tried several tests, including publishing the article in a testSetup method beforehand and calling a update viewstat query in the testSetup method, and each result was the same: no view stat records were created.

As such, you'll need "mock" around this somehow, probably by querying the data into a static or class variable, and then manipulating it from the unit test. There is no way that I could find to get a "real" view stat for an article created during a unit test.

  • Thanks @sfdcfox for the detailed answer, I too have tested the same and found same results but could not find any documentation specifying about this. Commented Dec 27, 2017 at 6:14

As per @sfdcfox, you are going to need to mock these using a mocking technique

Here's an example using ApexMocks and Force.com Enterprise Architetcure Selector layer (my example is Accounts but you can adapt for your use case)

Selector class

public virtual class AccountsSelector implements IAccountsSelector {
        Force.com Enterprise Architecture Separation of Concerns Selector Layer: Accounts
        All selectors follow this pattern. Enables mocking through the Application.Selector.setMock

        Account[] accts = AccountsSelector.newInstance().selectXXXX(args)

        See Force.com Enterprise Architecture 2nd Edition Chapter 7

    public override String getOrderby() {return 'Name';}        // default field to order results by if not otherwise specified

    public List<Schema.SObjectField> getSObjectFieldList() {    // keep in alpha order
        return new List<Schema.SObjectField> {  
            Account.MyCustomField__c,  // as needed

    *   Factory to provide caller with a new Selector. Enables selectors to be mocked 
    public static IAccountsSelector newInstance()    {
        return (IAccountsSelector) Application.Selector.newInstance(Account.SObjectType);

    *   getSObjectType : Used to construct queries. Required. 
    public Schema.SObjectType getSobjectType() {return Account.SObjectType;}

    *   selectById  : default selector, returns all matching SObjects for fields defined by getSObjectFieldList
    public virtual Account[] selectById(set<ID> ids) {
        return ids.isEmpty() ? new List<Account> () : (Account[]) selectSObjectsById(ids);

    *  custom selector
    public virtual Account[] selectByName(set<String> names) {
       fflib_QueryFactory aQF = newQueryFactory()
                                .setCondition('Name IN :names);
       return Database.query(aQF.toSOQL());

Use in code-under-test

Account[] accounts = AccountsSelector.newInstance()

Test method

   fflib_ApexMocks mocks = new fflib_ApexMocks();
   // Given mock Accounts selector
   AccountsSelector mockAcctsSelector = (AccountsSelector) mocks.mock(AccountsSelector.class);
   // Given stubbing for selector; for ViewStat, you may need to use sfab_SObjectFabricator or equivalent Json trick
   Account[] mockAccounts = new list<Account> {
               new Account(Id = ..., Name = ..., ...),
               new Account(...)
    // Given mocks injested

    // When relevant method under test
    new MyClass().myMethod();

    // Then verify
    ... asserts or mocks.verify as appropriate
  • Thank you @cropredy, This looks promising, I will explore the Force.com Enterprise Architecture Selector layer. Commented Dec 27, 2017 at 6:15
  • @SantanuHalder I have some blog posts on apexmocks at cropredysfdc.com after you absorb the Selector Layet (also described in Trailhead). ApexMocks is an investment in time that pays off. If you know Mockito from Java (I didn’t) it will be familiar.
    – cropredy
    Commented Dec 27, 2017 at 14:51

You must log in to answer this question.

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