I am trying to test a function that creates a message exchange graph from IRC chat logs. I am having trouble trying to mock the dependencies. The function makes use of util module. The functions inside utils receive arguments and return an output after some processing. The problem is that these utils functions are being called multiple times inside for-loops and if-conditionals. How do I specify multiple returns based on input arguments? I would like to know how to unit-test functions similar to these.

I have been using python standard unittest and mock libraries.

Source of the code: IRCLogParser

def message_number_graph(log_dict, nicks, nick_same_list,DAY_BY_DAY_ANALYSIS=False):
    Creates a directed graph
    with each node representing an IRC user
    and each directed edge has a weight which 
    mentions the number messages sent and recieved by that user 
    in the selected time frame.

    log_dict (dict): with key as dateTime.date object and value as {"data":datalist,"channel_name":channels name}
    nicks(list): list of all the nicks
    nick_same_list(list): list of lists mentioning nicks which belong to same users
   message_number_graph (nx graph object)
message_number_day_list = []
conversations=[[0] for i in range(config.MAX_EXPECTED_DIFF_NICKS)]
aggregate_message_number_graph = nx.DiGraph()  #graph with multiple directed edges between clients used

G = util.to_graph(nick_same_list)
conn_comp_list = list(connected_components(G))


def msg_no_analysis_helper(rec_list, corrected_nick, nick, conn_comp_list,conversations,today_conversation):
    for receiver in rec_list:
        if(receiver == nick):
            if(corrected_nick != nick):                                 
                nick_receiver = ''
                nick_receiver = util.get_nick_sen_rec(config.MAX_EXPECTED_DIFF_NICKS, nick, conn_comp_list, nick_receiver)    

                if DAY_BY_DAY_ANALYSIS:
                    today_conversation = util.extend_conversation_list(nick_sender, nick_receiver, today_conversation)
                    conversations = util.extend_conversation_list(nick_sender, nick_receiver, conversations)

def message_no_add_egde(message_graph, conversation):
    for index in xrange(config.MAX_EXPECTED_DIFF_NICKS):
        if(len(conversation[index]) == 3 and conversation[index][0] >= config.THRESHOLD_MESSAGE_NUMBER_GRAPH):
            if len(conversation[index][1]) >= config.MINIMUM_NICK_LENGTH and len(conversation[index][2]) >= config.MINIMUM_NICK_LENGTH:
                message_graph.add_edge(util.get_nick_representative(nicks, nick_same_list, conversation[index][1]), util.get_nick_representative(nicks, nick_same_list, conversation[index][2]), weight=conversation[index][0])
    return message_graph

for day_content_all_channels in log_dict.values():
    for day_content in day_content_all_channels:
        day_log = day_content["log_data"]
        today_conversation = [[0] for i in range(config.MAX_EXPECTED_DIFF_NICKS)]
        for line in day_log:
            flag_comma = 0

            if(util.check_if_msg_line (line)):
                parsed_nick = re.search(r"\<(.*?)\>", line)
                corrected_nick = util.correctLastCharCR(parsed_nick.group(0)[1:-1])
                nick_sender = ""
                nick_receiver = ""                    
                nick_sender = util.get_nick_sen_rec(config.MAX_EXPECTED_DIFF_NICKS, corrected_nick, conn_comp_list, nick_sender)        

                for nick in nicks:
                    rec_list = [e.strip() for e in line.split(':')]
                    if not rec_list[1]:
                    rec_list = util.correct_last_char_list(rec_list)       
                    msg_no_analysis_helper(rec_list, corrected_nick, nick, conn_comp_list, conversations,today_conversation)

                    if "," in rec_list[1]:
                        flag_comma = 1
                        rec_list_2=[e.strip() for e in rec_list[1].split(',')]
                        for i in xrange(0,len(rec_list_2)):
                                rec_list_2[i] = util.correctLastCharCR(rec_list_2[i])                            
                        msg_no_analysis_helper(rec_list_2, corrected_nick, nick, conn_comp_list, conversations, today_conversation)                

                    if(flag_comma == 0):
                        rec = line[line.find(">")+1:line.find(", ")]
                        rec = rec[1:]
                        rec = util.correctLastCharCR(rec)
                        if(rec == nick):
                            if(corrected_nick != nick):                                   
                                nick_receiver = nick_receiver_from_conn_comp(nick, conn_comp_list)        

            today_message_number_graph = nx.DiGraph()
            today_message_number_graph = message_no_add_egde(today_message_number_graph, today_conversation)                
            year, month, day = util.get_year_month_day(day_content)
            message_number_day_list.append([today_message_number_graph, year+'-'+month+'-'+day])

print "\nBuilding graph object with EDGE WEIGHT THRESHOLD:", config.THRESHOLD_MESSAGE_NUMBER_GRAPH

    aggregate_message_number_graph = message_no_add_egde(aggregate_message_number_graph, conversations)

if config.DEBUGGER:
    print "========> 30 on " + str(len(conversations)) + " conversations"
    print conversations[:30]

    return message_number_day_list
    return aggregate_message_number_graph
  • 3
    Are you sure you want to mock the util module? Is the util module already unit-tested and under your control? Perhaps you can use the real util module then? – user285148 Jan 17 '18 at 6:53

First wrap the util class and add a logger to log all the calls and return values produced by a real run through, saving them to a file.

Then create a mocked util class which reads the file, compares its input with previously recorded input and returns the selected result.

In your tests initialise your util mock with a correct prerecorded file for each test.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.