2

I'm trying to save on boilerplate code so tried to use { get; set; } idiom, but the function will not resolve.

This is the class with decorated properties.

public class Counter {
    private static Integer hits {get { if(hits == null) hits = 0; hits++; return hits; } private set; }
    private static Boolean foo {get;set;}
}

My unit test, that will not build, I get the error: Method does not exist or incorrect signature: void getHits() from the type Counter on every assert line.

@isTest public class CounterTest extends AbstractTestCase {
    @isTest static void testCounter() {
        Test.startTest();
        Counter count = new Counter();
        assertNotNull(count);

        // instance access, case sensitive and insensitive
        System.assert(count.getHits() == 1);
        System.assert(count.gethits() == 1);

        // static access, case sensitive and insensitive
        System.assert(Counter.getHits() == 2);
        System.assert(Counter.gethits() == 2);

        // even trivial example doesn't work
        count.setFoo(true);
        System.assert(getFoo());

        // I even tried direct access, 
        System.debug('count : ' + Counter.hits);        
        System.assert(Counter.hits == 1);
        Test.stopTest();
    }
}

I've using v44 of apex, how on earth are these used?

Yes, there are lot of questions about { get; set; } but non address this specific point

1

2 Answers 2

6

From Apex, you reference it the same as if it didn't have a getter or setter defined. The fact that it is private means you will need to use the @TestVisible annotation if you want to test against it, but also strongly indicates you shouldn't be testing it, or it shouldn't be private. Usually I will use a public getter and private setter.

public Integer myAttribute { get; private set; }

Once you do that, the reference is simply:

system.assertEquals(1, Counter.hits);

Please note that you should always prefer assertEquals(expected, observed) over assert(expected == observed), and that the expected value comes first. Following these rules will give you much clearer assertion failures, as would including a useful message (the optional third parameter).

2
  • 1
    So 'private' applies to the get/set and not just the property, I expected the property to be private and the get/set to be implicitly public, which is why I expressly made the set private and left the set as default. so much for the principle of least astonishment. :) Jan 18, 2019 at 9:35
  • They inherit unless you specify an override.
    – Adrian Larson
    Jan 18, 2019 at 14:18
3

To clarify the syntax (if hits wasn't static):

count.hits = 1; // calls the "set"
Integer foo = count.hits; // calls the "get"

You can't call count.getHits(). The calling syntax looks just like accessing a field.

However, since "hits" is static, it is not tied to an instance of your class, but to your class directly. You would access it as Counter.hits.

Then, you'll need to do something about visibility; either annotate with TestVisible, or make the property public.

You must log in to answer this question.

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