mirror of
https://github.com/HackSoftware/Django-Styleguide.git
synced 2024-11-10 19:56:40 +03:00
Merge pull request #10 from HackSoftware/testing/selectors
Testing: Selectors
This commit is contained in:
commit
3641822af9
75
README.md
75
README.md
|
@ -34,6 +34,7 @@ Expect often updates as we discuss & decide upon different things.
|
|||
+ [Example selectors](#example-selectors)
|
||||
+ [Example services](#example-services)
|
||||
* [Testing services](#testing-services)
|
||||
* [Testing selectors](#testing-selectors)
|
||||
- [Inspiration](#inspiration)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
@ -693,7 +694,7 @@ from django.contrib.auth.models import User
|
|||
|
||||
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(
|
||||
|
@ -749,6 +750,7 @@ When creating the required state for a given test, one can use a combination of:
|
|||
* 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))
|
||||
* Plain `Model.object.create()` calls, if factories are not yet introduced in the project.
|
||||
|
||||
**Lets take a look at our service from the example:**
|
||||
|
||||
|
@ -839,6 +841,77 @@ class BuyItemTests(TestCase):
|
|||
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
|
||||
|
||||
The way we do Django is inspired by the following things:
|
||||
|
|
Loading…
Reference in New Issue
Block a user