mardi 6 août 2019

How to use Pytest-mock for testing the output

I use below code to test if account is registered successfully.

@pytest.fixture(scope="function")
def ctrl():
    view = RegisterUI()
    return RegisterController(view)

def test_canCreateAccount(ctrl, mocker):
    mocker.patch('ctrl.view.getEmail', return_value ='hello@gmail.com')
    mocker.patch('ctrl.view.getPassword1', return_value='1234567')
    mocker.patch('ctrl.view.getPassword2', return_value='1234567')
    mocker.patch('ctrl.view.getSecKey', return_value='dog')
    account = ctrl.createAccount()
    assert account.email == 'hello@gmail.com'

However, it show an error:

    def test_canCreateAccount(ctrl, mocker):
>       mocker.patch('ctrl.view.getEmail', return_value ='hello@gmail.com')

Sub2_Account_Register.py:131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\AppData\Roaming\Python\Python37\site-packages\pytest_mock.py:158: in __call__
    return self._start_patch(self.mock_module.patch, *args, **kwargs)
..\..\..\AppData\Roaming\Python\Python37\site-packages\pytest_mock.py:138: in _start_patch
    mocked = p.start()
..\..\..\AppData\Local\Programs\Python\Python37\lib\unittest\mock.py:1399: in start
    result = self.__enter__()
..\..\..\AppData\Local\Programs\Python\Python37\lib\unittest\mock.py:1252: in __enter__
    self.target = self.getter()
..\..\..\AppData\Local\Programs\Python\Python37\lib\unittest\mock.py:1422: in <lambda>
    getter = lambda: _importer(target)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

target = 'ctrl.view'

    def _importer(target):
        components = target.split('.')
        import_path = components.pop(0)
>       thing = __import__(import_path)
E       ModuleNotFoundError: No module named 'ctrl'

..\..\..\AppData\Local\Programs\Python\Python37\lib\unittest\mock.py:1105: ModuleNotFoundError

So how to fix it ? Also, how to test if the message "Account was registerd successfully" was called ?

A member told me that I can use pytest-mock to mock displaymessage() function to check whether it was called or not and check what argument it was called with if called. However, I don't know how to do that. How to implement it correctly ?

This is my code:


class CreateAccountFailed(Exception):
    pass


class PassNotValid(CreateAccountFailed):
    pass


class PassNotMatch(CreateAccountFailed):
    pass


class EmailNotOK(CreateAccountFailed):
    pass


class RegisterUI:

    def getEmail(self):
        return input("Please type an your email:")

    def getPassword1(self):
        return input("Please type a password:")

    def getPassword2(self):
        return input("Please confirm your password:")

    def getSecKey(self):
        return input("Please type your security keyword:")

    def printMessage(self, message):
        print(message)


class RegisterController:
    def __init__(self, view):
        self.view = view

    def displaymessage(self, message):
        self.view.printMessage(message)

    def ValidateEmail(self, email):
        email_obj = Email(email)
        return email_obj.isValidEmail() and not accounts.isDuplicate(email)

    def ValidatePassword(self, password):
        return Password.isValidPassword(password)

    def CheckPasswordMatch(self, password1, password2):
        return Password.isMatch(password1, password2)

    def makeAccount(self, email, password, seckey):
        return Account(Email(email), Password(password), seckey)

    def askForValidEmail(self):
        for x in range(0, 3):
            email = self.view.getEmail()
            if self.ValidateEmail(email):
                return email
            else:
                self.displaymessage("Email was invalid or a duplicate, please try again")
        raise EmailNotOK

    def askForValidPassword(self):
        while 1:
            password1 = self.view.getPassword1()
            password2 = self.view.getPassword2()
            if not Password.isMatch(password1, password2):
                self.displaymessage("The passwords do not match")
            elif not Password.isValidPassword(password1):
                self.displaymessage("The password is invalid")
            else:
                return password1

    def createAccount(self):
        email = self.askForValidEmail()
        password = self.askForValidPassword()
        account = self.makeAccount(email, password, self.view.getSecKey())
        self.displaymessage("Account was registerd successfully")
        return account


class Register(Option):
    def execute(self):
        view = RegisterUI()
        controller_one = RegisterController(view)
        controller_one.createAccount()

Aucun commentaire:

Enregistrer un commentaire