apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
911 stars 517 forks source link

Should we do Assertions to check the value changed in the Database when using the Test Mock Framework? #374

Closed AllanOricil closed 3 years ago

AllanOricil commented 3 years ago

In this test we can see that an Update happened, but there is no assertion to check that the Value actually changed. Is it sufficient to check that the method was called?

wimvelzeboer commented 3 years ago

Hi @AllanOricil, If there happend an actual database base operation, then thats I would classify that as a bug.

The intention of this test is to mock the unitOfWork so that no actual database operation is being performed. It creates test data, with fake ID's, and mocks the UnitOfWork, Domain and Selector.

In the // THEN part of the test, there are a number of "assertions" to verify that the methods are invoked, including the call to registerDirty, and the commitWork. As they are part of a mocked UnitOfWork, there will be no actual DML operation.

Are you sure it performs a DML operation currently?

AllanOricil commented 3 years ago

@wimvelzeboer Ok, so because we Mocked the Unit of Work, the DML operations didnt happen actually. This means there is no need to query the records and assert if they were changed. But we should "verify" that they were called as we would expect. Thanks

AllanOricil commented 3 years ago

I got confused because Im used make DML operations on my tests.

wimvelzeboer commented 3 years ago

@AllanOricil Yes indeed, we mock all the interactions with the database. So that there will be no queries and no DML statements. But we do need to make sure the records were send to the database (/mock), and we use the verify methods to assert for that.

The major benefit of mocking is that unit test only test the method that we are testing and nothing else, resulting in much faster test execution time. When all the tests in a Apex test class are using mocking, you can also enable paralel test execution, making it even faster.

Another benefit is that you don't need to care about creating a whole hierarchy of test data, usually only records with a minimal setup are already good enough to run your test. Mandatory fields that we do not use in the test... we don't care... :-) But I do have to say, sometimes it can be tricky to setup test data for mocking, it's responding slightly different than actual tests.