-1

I'm reading about property based testing and I'm wondering how can I test this my code using that paradigm.

class Invoice {

    private final String id;
    private final String companyName;

    public String name() {
        return id + "_" + removeDots(companyName.trim());
    }

}

I want to test Invoice::name method, so I would do something like this:

class InvoiceTest {

    //Let's say 'id' and 'companyName' are random auto-generated values
    //by some framework
    @Test 
    public void nameTest(String id, String companyName) {
        Invoice invoice = new Invoice(id, companyName);
        assertThat(invoice.name()).isEqualTo(id + "_" + removeDots(companyName.trim()));
    }

}

As you see, it makes no sense. I'm reimplementing the logic in the test method. Maybe, is property based testing suitable only for "mathematical" logic?

5
  • "Property-based testing" in the context you've illustrated in your question is no different from method or function testing. The same rules and regulations apply. Commented Nov 15, 2018 at 16:55
  • So, are just "mathematical" or arithmetic contexts where PBT should be applied? Commented Nov 15, 2018 at 16:57
  • 2
    Have a look at the illustration provided here. "A property is a high-level specification of behavior that should hold for a range of data points. For example, a property might state that the size of a list returned from a method should always be greater than or equal to the size of the list passed to that method." Commented Nov 15, 2018 at 17:01
  • 1
    "The difference between a traditional test and a property is that tests traditionally verify behavior based on specific data points checked by the test. A test might pass three or four specific lists of different sizes to a method under test that takes a list, for example, and check the results are as expected. A property, by contrast, would describe at a high level the preconditions of the method under test and specify some aspect of the result that should hold no matter what valid list is passed." Commented Nov 15, 2018 at 17:02
  • Understood. So property based testing is to verify domain invariants. Thank you very much Commented Nov 15, 2018 at 17:05

1 Answer 1

3

Maybe, is property based testing suitable only for "mathematical" logic?

Not necessarily.

Writing tests first forces you to think about the problem you're solving. Writing property-based tests forces you to think way harder. -- Jessica Kerr

boolean hasDots(String candidate) { ... }

@Test
public void it_removes_the_dots(String anyCompanyName) {
    String id = "0";
    Invoice invoice = new Invoice(id, anyCompanyName);
    String name = invoice.name();

    assertFalse( hasDots(name) );
}

@Test
public void it_leaves_the_same_when_no_dots(String anyCompanyNameWithoutDots) {
    assume ! hasDots(anyCompanyNameWithoutDots);

    String id = "0";
    Invoice invoice = new Invoice(id, anyCompanyNameWithoutDots);
    String invoiceName = invoice.name()

    assertTrue(invoiceName.endsWith(anyCompanyNameWithoutDots));
}

@Test
public void it_prepends_the_identifier_without_changing_it(String anyIdentifier) {
    String companyName = "BobsBoringBusiness";
    Invoice invoice = new Invoice(anyIdentifier, companyName );
    String invoiceName = invoice.name()

    assertTrue(invoiceName.startsWith(anyIdentifier));
}


@Test
public void it_prepends_the_identifier_without_removing_dots(String anyIdentifierWithDots) {
    assume hasDots(anyIdentifierWithDots);

    String companyName = "BobsBoringBusiness";
    Invoice invoice = new Invoice(anyIdentifierWithDots, companyName );
    String invoiceName = invoice.name()

    assertTrue(invoiceName.startsWith(anyIdentifierWithDots));
}
// ... and so on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.