mirror of
https://github.com/HackSoftware/Django-Styleguide.git
synced 2024-11-11 04:06:46 +03:00
Add section for Testing selectors
This commit is contained in:
parent
6df34b29b6
commit
a1ef1c1347
74
README.md
74
README.md
|
@ -693,7 +693,7 @@ from django.contrib.auth.models import User
|
||||||
|
|
||||||
from django_styleguide.common.types import QuerySetType
|
from django_styleguide.common.types import QuerySetType
|
||||||
|
|
||||||
from django_styleguide.payments.models import Item, Payment
|
from django_styleguide.payments.models import Item
|
||||||
|
|
||||||
|
|
||||||
def get_items_for_user(
|
def get_items_for_user(
|
||||||
|
@ -749,6 +749,7 @@ When creating the required state for a given test, one can use a combination of:
|
||||||
* Other services, to create the required objects.
|
* Other services, to create the required objects.
|
||||||
* Special test utility & helper methods.
|
* Special test utility & helper methods.
|
||||||
* Factories (We recommend using [`factory_boy`](https://factoryboy.readthedocs.io/en/latest/orms.html))
|
* Factories (We recommend using [`factory_boy`](https://factoryboy.readthedocs.io/en/latest/orms.html))
|
||||||
|
* Plain `Model.object.create()` calls, if factories are not yet introduced in the project.
|
||||||
|
|
||||||
**Lets take a look at our service from the example:**
|
**Lets take a look at our service from the example:**
|
||||||
|
|
||||||
|
@ -839,6 +840,77 @@ class BuyItemTests(TestCase):
|
||||||
charge_payment_mock.assert_called()
|
charge_payment_mock.assert_called()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Testing selectors
|
||||||
|
|
||||||
|
Testing selectors is also an important part of every project.
|
||||||
|
|
||||||
|
Sometimes, the selectors can be really straightforward, and if we have to "cut corners", we can omit those tests. But it the end, it's important to cover our selectors too.
|
||||||
|
|
||||||
|
Lets take another look at our example selector:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from django_styleguide.common.types import QuerySetType
|
||||||
|
|
||||||
|
from django_styleguide.payments.models import Item
|
||||||
|
|
||||||
|
|
||||||
|
def get_items_for_user(
|
||||||
|
*,
|
||||||
|
user: User
|
||||||
|
) -> QuerySetType[Item]:
|
||||||
|
return Item.objects.filter(payments__user=user)
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, this is a very straighforward & simple selector. We can easily cover that with 2 to 3 tests.
|
||||||
|
|
||||||
|
**Here are the tests:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from django_styleguide.payments.selectors import get_items_for_user
|
||||||
|
from django_styleguide.payments.models import Item, Payment
|
||||||
|
|
||||||
|
|
||||||
|
class GetItemsForUserTests(TestCase):
|
||||||
|
def test_selector_returns_nothing_for_user_without_items(self):
|
||||||
|
"""
|
||||||
|
This is a "corner case" test.
|
||||||
|
We should get nothing if the user has no items.
|
||||||
|
"""
|
||||||
|
user = User.objects.create_user(username='Test User')
|
||||||
|
|
||||||
|
expected = []
|
||||||
|
result = list(get_items_for_user(user=user))
|
||||||
|
|
||||||
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
|
def test_selector_returns_item_for_user_with_that_item(self):
|
||||||
|
"""
|
||||||
|
This test will fail in case we change the model structure.
|
||||||
|
"""
|
||||||
|
user = User.objects.create_user(username='Test User')
|
||||||
|
|
||||||
|
item = Item.objects.create(
|
||||||
|
name='Test Item',
|
||||||
|
description='Test Item description',
|
||||||
|
price=10.15
|
||||||
|
)
|
||||||
|
|
||||||
|
Payment.objects.create(
|
||||||
|
item=item,
|
||||||
|
user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
expected = [item]
|
||||||
|
result = list(get_items_for_user(user=user))
|
||||||
|
|
||||||
|
self.assertEqual(expected, result)
|
||||||
|
```
|
||||||
|
|
||||||
## Inspiration
|
## Inspiration
|
||||||
|
|
||||||
The way we do Django is inspired by the following things:
|
The way we do Django is inspired by the following things:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user