Some weeks (perhaps months) ago, I posted a question about testing
and got many responses but had trouble grasping the concepts
so I settled on the suggestion that I thought would be the easiest
to implement (using unittest.mock.) Here it is-

"""
from Peter Otten:
I find Ben's example instructive, but when you're just starting you
might prefer a simpler approach:

import unittest
from unittest import mock
import mycode

class TestCollectData(unittest.TestCase):
    def test(self):
        with mock.patch(
                "builtins.input",
                side_effect=["foo", "bar", "baz"]):
            self.assertEqual(
                mycode.collect_data(),
                dict(first="foo", last="bar", phone="baz"))

if __name__ == "__main__":
    unittest.main()
"""

I've successfully implemented mock.patch parameters but don't
understand how to implement the parameters for the assertEqual
call as it pertains to my particular situation.

My current code sort of does the job but determinating success or
failure is not really automated.

It's Python 3 on Ubuntu 14.4LTS.
My test code and the tested code follow.  Any suggestions would be
most welcome.  Thanks in advance.
Alex

Test Code:
#!../../venv/bin/python
# -*- coding: utf-8 -*-
# vim: set file encoding=utf-8
"""
Attempt to automate testing of menu module.
"""
import unittest
from unittest import mock
import menu

class MenuTests(unittest.TestCase):

    def test_create_new(self):
        with mock.patch("builtins.input",
                side_effect=['1', 'testentity', '', '0']):
            menu.menu()

if __name__ == '__main__':  # code block to run the application
    unittest.main()


Tested code:

#!../../venv/bin/python
# -*- coding: utf-8 -*-
# vim: set file encoding=utf-8
"""
A simple menu model used to format a question
about how to test using unittest.mock.
"""

class Entities(object):
    """
    Keep track of the entities including a default.
    Expect only one instance which will be a global.
    """

    def __init__(self, list_of_entities, default=''):
        self._list = list_of_entities
        self.default = default

    def get_default(self):
        return self.default

    def reset_default(self, default=''):
        self.default = default

    def get_list(self):
        return self._list

    def add(self, new_entity, set_default=False):
        """
        Adds another entity returning it to signal success.
        Returns None if entity is unacceptable.
        """
        if (not new_entity in self._list
        and new_entity.isalnum()
        and new_entity[0:1].isalpha()):
            self._list.append(new_entity)
            if set_default:
                self.reset_default(new_entity)
            return new_entity
        else:
            print("Failing to add an invalid entity: '{}'."
                        .format(new_entity))

    def get_new_entity(self):
        """
        Prompts user for a new entity which, if valid, is
        returned after being appended to list and set as default.
        Returns None if fails to create a new entity.
        """
        while True:
            new_entity = input("Pick name for new entity: ")
            if not new_entity: return
            if new_entity != self.add(new_entity, set_default=True):
                continue
            else:
                return new_entity

    def remove(self, entity2remove):
        if not entity2remove in self.get_list():
            print("Can't remove '{}': not in the list."
                        .format(entity2remove))
            return
        if entity2remove == self.get_default():
            self.reset_default()
        self._list = [entity for entity in self._list
                        if entity!=entity2remove]

    def show_listing(self):
        """
        Returns a string listing the available entities.
        Empty string if there are no entities.
        """
        return ''.join(["\n\t    {}".format(entity)
                        for entity in self.get_list()])

    def entity_choice(self, set_default=False):
        """
        Prompts the user to choose from the list.
        Returns a valid choice or None.
        Can optionally set the default to the chosen entity.
        """
        list_of_entities= self.get_list()
        if not list_of_entities:
            print("There are no entities from which to choose.")
            return
        default_line = ''
         if self.default:
            default_line = ("\n\t_: Default is '{}', just hit enter."
                                .format(self.default))
        menu = ('\n'.join(["\t{}: {}".format(n, entity)
                for (n, entity) in enumerate(list_of_entities, 1)])
                + default_line)
        while True:
            option = input(
    """Choose one of the following:
    {}
    \t0: to exit.
    Pick an entity: """.format(menu))
            default = self.get_default()
            if (option=='' or option=='_') and default:
                return default
            try:
                option = int(option)
            except ValueError:
                print("Invalid option: {}! (It must be an integer.)"
                        .format(option))
                continue
            entity_list = self.get_list()
            if option in range(1, len(entity_list) + 1):
                choice = entity_list[option - 1]
                if set_default:
                    self.default = choice
                return choice
            elif option == 0:
                return None
            else:
                print("Invalid entry- try again ('0' to quit.)")

def create_new(option, entities):
    """
    A main menu response function.
    """
    print("Picked '{}. Create a new entity.'".format(option))
    entity = entities.get_new_entity()
    if entity:
        print(
            "Entity '{}' successfully created (and set as default.)"
                .format(entity))
        work_with(entity)
    else:
        print("Aborting entity creation.")

def choose_existing(option, entities):
    """
    A main menu response function.
    """
    print("Picked '{}'. Choose an entity."
            .format(option))
    choice = entities.entity_choice(set_default=True)
    if choice:
        work_with(choice)

def delete_option(option, entities):
    """
    A main menu response function.
    """
    print("Picked '{}. Delete an existing entity.'".format(option))
    while True:
        entity = entities.entity_choice()
        if not entity:
            print("Entity deletion aborted.")
            return
        y_n = input("About to delete entity '{}', ARE YOU SURE? "
                .format(entity))
        if y_n and y_n[0] in 'Yy':
            print("Deleting entity '{}'.".format(entity))
            entities.remove(entity)
        else:
            print("No deletion being done.")
        break

def work_with(entity):
    """
    Provides an interface stub for once an entity has been selected.
    """
    _ = input("Stub of code to work with '{}' entity goes here."
                    .format(entity))

def menu():
    """
    Provides the top level user interface.
    """
    entities = Entities(["ent1", "ent2", "ent3"], "ent2")
    while True:
        listing = entities.show_listing()
        if listing:
            listing = (
"""\n(  Currently existing entities are: {}          )"""
                    .format(listing))
        option = input("""
Main Menu:{}
    1. Create a new entity.
    2. Choose an existing entity.
    9. Delete an entity.
    0. Exit
Choice: """
                        .format(listing))
        print("Main Menu choice: {}".format(option))
        if option in ('', '_', '0'):
            return
        try:
            option = int(option)
        except ValueError:
            print(
                "Invalid main menu choice: {} (must be an integer.)"
                        .format(option))
            continue
        if option == 1:
            entity = create_new(option, entities)
        elif option == 2:
            entity = choose_existing(option, entities)
        elif option == 9:
            delete_option(option, entities)
            entity = ''
         else:
            print("BAD CHOICE '{}'- try again....".format(option))
            entity = None
        if entity:
            work_with(entity)

if __name__ == "__main__":
    menu()
~

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to