Does TDD crash in Python?

Suppose we have a class UserServicewith an attribute current_user. Suppose it is used in a class AppService.

We have AppServicecovered in tests. In the test setup, we cross out current_userwith some mock value:

UserService.current_user = 'TestUser'

Suppose we decide to rename current_userto active_user. We will rename it to UserService, but forget to make changes to its use at AppService.

We run the tests and they pass! In the test setup, an attribute is added current_user, which is still (erroneously, but successfully) used in AppService.

Now our tests are useless. They pass, but the application does not work.

We cannot rely on our test suite ==> TDD is not possible.

Does TDD crash in Python?

+3
source share
3 answers

OK, I found a solution. The Python library Mock does what I want .

Below is the code I'm finishing in.

Definition of model and service:

class User(object):
    def __init__(self):
        self.roles = []


class UserService(object):
    def get_current_user(self):
        return None # get from environment, database, etc.

    current_user = property(get_current_user)


class AppService(object):
    def __init__(self, userService):
        self.userService = userService

    def can_write(self):
        return 'admin' in self.userService.current_user.roles

Here's how to test a method can_write AppServicewith different users:

class AppServiceTests(unittest.TestCase):
    def test_can_write(self):
        user = User()

        @patch_object(UserService, 'current_user', user)
        def can_write():
            appService = AppService(UserService())
            return appService.can_write()

        user.roles = ['admin']
        self.assertTrue(can_write())

        user.roles = ['user']
        self.assertFalse(can_write())

If you rename a property current_useronly in a class UserService, you will get an error when trying to fix an object. This is the behavior I was looking for.

+1
source

TDD, Python. , TDD , , , . , . multiplyBy2(), 1,2,3 2,4,8, , multiplyBy2 . , 100% - , . , TDD , , , - , , . , , , , . - , . , , , . , , , , , , , .

+2

- , current_user. - (). ; :

UserService.current_user = 'X'
assertFalse(obj.predicate())
UserService.current_user = 'Y'
assertTrue(obj.predicate())

OK? , . . , current_user active_user. , . , current_user, . , , , .

0

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


All Articles