Do matches match ActiveRecord applicants to comply with the rules of "test behavior, not implementation"?

For example, if I use should validate_presence_of in my spec, it is only testing that I have the code validate_presence_of code inside my model and this testing implementation. More importantly, isn't it completely useless to test a real problem, namely: "If I don't fill in a specific field, will the model be successfully saved?"

+4
source share
1 answer

Some of them that do not test the implementation do not test the implementation. They show test behavior. For example, look at the source for allow_value (which is used by validate_presence_of ): #matches? actually sets the instance attribute to a value and checks to see if it causes an error. All matches that validate ( ActiveModel matchers ) that I looked at work the same way; they actually verify that the model rejects the bad values.

Note that if you trust ActiveModel and ActiveRecord for a full check, it doesn't matter if the behavior of the testers is checked or just made sure that macros are used.

Reasonably useful to test model testing. Suppose you make a BDD and implement a simple form that instantiates a model. First you must write a acceptance test (Cucumber or rspec script) that checks the happy form fill path correctly and successfully creates an instance. Then you should record the second acceptance test with an error in the form, which demonstrates that if there is no error in the form, the instance is not saved and the form is displayed again with the corresponding error message.

Once you have this error scenario for one of the errors, you can make it in the form, you will find that if you write more error error scenarios for other errors, they will be very repetitive - the only things that will differ are the erroneous value of the field and error message. And then you will have many full stack scripts that take a lot of time. Therefore, do not write more than the first error scenario. Instead, just write unit tests for checks that will catch every error. Now most of your tests are simple and fast. (This is a concrete example of a general BDD technique for rejecting acceptance tests for unit tests for part processing.)

However, I do not consider it appropriate to use ActiveRecord matchers . . Considering the matches that test associations, I believe that my acceptance tests always force me to add all the associations to my models that I need, and there is nothing left in the unit tests. ActiveRecord attributes that test database functions that are invisible to the application (e.g. have_db_index ) are useful if you are strictly controlled by testing, but I am inclined to this. Also, for what it's worth, ActiveRecord adapters don't test behavior (which would be hard to implement), just to use the appropriate macros.

The only exception in which I find a suitable ActiveRecord helper is deleting dependent objects. Sometimes it seems to me that no action of acceptance has already forced me to process what happens to related objects when the object is deleted. The ActiveRecord way to do this is to add a :dependent parameter to the belongs_to , has_many or has_one . Writing an example using the helper commands " belong_to " or have_many or have_one with the .dependent option is the most convenient way that I know to test this.

+7
source

Source: https://habr.com/ru/post/1247627/


All Articles