'PK incrementing when adding new TestCase

I realized when I'm adding new TestCase PK in old TestCase is incrementing. For example, I'm testing .get_absolute_url method:

def get_absolute_url(self):
  return reverse('linkdetail', kwargs={'pk': self.pk})

with this test

def test_get_absolute_url(self):
  obj = Link.objects.get(title="test_tile")
  self.assertEqual(obj.get_absolute_url(), "/link/1/")

and to this point everything is okay and test is passing, but when I add another TestCase

class LinkCommentTestCase(TestCase):
    def setUp(self):
        user = User.objects.create(username="test",
                                   password="asd")
        link = Link.objects.create(title="test_tile2",
                                   link="http://google.com",
                                   author=user)
        comment = LinkComment.objects.create(author=user,
                                             link=link,
                                             content="asd")

    def test_get_comments_count(self):
        obj = LinkComment.objects.get(content="asd")

im getting this error

======================================================================
FAIL: test_get_absolute_url (links.tests.test_models.LinkTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/x/Desktop/x/links/tests/test_models.py", line 72, in test_get_absolute_url
    self.assertEqual(obj.get_absolute_url(), "/link/1/")
AssertionError: '/link/2/' != '/link/1/'
- /link/2/
?       ^
+ /link/1/
?  

Why is this happening and how can I prevent this?



Solution 1:[1]

Don't hardcode the pk, create the expected URL dynamically.

def test_get_absolute_url(self):
    obj = Link.objects.get(title="test_tile")
    self.assertEqual(obj.get_absolute_url(), f"/link/{obj.pk}/")

You can't be sure that your test object will always get the same pk

You could test the result of a GET to the returned URL if you don't want to dynamically create the expected URL

def test_get_absolute_url(self):
    obj = Link.objects.get(title="test_tile")
    response = self.client.get(obj.get_absolute_url())
    self.assertEqual(response.status_code, 200)

    # Test for func based view matched
    self.assertEqual(response.resolver_match.func, link_detail)

    # Test for class based view matched
    self.assertEqual(response.resolver_match.func.__name__, LinkDetail.as_view().__name__)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1