Move example code to its own section

This commit is contained in:
Radoslav Georgiev 2019-01-20 17:18:08 +02:00
parent 7b8155e7b1
commit e986d86608

View File

@ -627,24 +627,11 @@ If we are to split the `utils.py` module into submodules, the same will happen f
We try to match the stucture of our modules with the structure of their respective tests. We try to match the stucture of our modules with the structure of their respective tests.
### Services ### Example
Service tests are the most important tests in the project. Usually, those are the heavier tests with most lines of code. We have a demo `django_styleguide` project.
General rule of thumb for service tests: #### Example models
* The tests should cover the business logic behind the services in an exhaustive manner.
* The tests should hit the database - creating & reading from it.
* The tests should mock async task calls & everything that goes outside the project.
When creating the required state for a given test, one can use a combination of:
* Fakes (We recommend using <https://github.com/joke2k/faker>)
* Other services, to create the required objects.
* Special test utility & helper methods.
* Factories (We recommend using [`factory_boy`](https://factoryboy.readthedocs.io/en/latest/orms.html))
Lets see an example. We have a demo `django_styleguide` project with the following models:
```python ```python
import uuid import uuid
@ -693,7 +680,7 @@ class Payment(models.Model):
return f'Payment for {self.item} / {self.user}' return f'Payment for {self.item} / {self.user}'
``` ```
**This is our selector:** #### Example selectors
For implementation of `QuerySetType`, check `types.py`. For implementation of `QuerySetType`, check `types.py`.
@ -712,7 +699,7 @@ def get_items_for_user(
return Item.objects.filter(payments__user=user) return Item.objects.filter(payments__user=user)
``` ```
**This is our service:** #### Example services
```python ```python
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -742,6 +729,54 @@ def buy_item(
return payment return payment
``` ```
### Testing services
Service tests are the most important tests in the project. Usually, those are the heavier tests with most lines of code.
General rule of thumb for service tests:
* The tests should cover the business logic behind the services in an exhaustive manner.
* The tests should hit the database - creating & reading from it.
* The tests should mock async task calls & everything that goes outside the project.
When creating the required state for a given test, one can use a combination of:
* Fakes (We recommend using <https://github.com/joke2k/faker>)
* Other services, to create the required objects.
* Special test utility & helper methods.
* Factories (We recommend using [`factory_boy`](https://factoryboy.readthedocs.io/en/latest/orms.html))
**Lets take a look at our service from the example:**
```python
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django_styleguide.payments.selectors import get_items_for_user
from django_styleguide.payments.models import Item, Payment
from django_styleguide.payments.tasks import charge_payment
def buy_item(
*,
item: Item,
user: User,
) -> Payment:
if item in get_items_for_user(user=user):
raise ValidationError(f'Item {item} already in {user} items.')
payment = Payment.objects.create(
item=item,
user=user,
successful=False
)
charge_payment.delay(payment_id=payment.id)
return payment
```
The service: The service:
* Calls a selector for validation * Calls a selector for validation