I created a Player class that is used to subscribe to a game server as well as responding to pings and applying the AI's algorithm moves. The class works as intended but I am trying to test the functions within it and I am having issues.
Here is my class code:
import socket
import json
import threading
import time
class Player:
"""
The Player class is used to subscribe to the game server as well
as responding to pings and applying the AI's algorithm moves
"""
def __init__(self, sub_address, game_address, name, matricules):
self.sub_address = sub_address #input an adress tuple(host, port) for subscribtion processes and Player info passing to game server
self.game_address = game_address #input an adress tuple(host, port) for ping and game comunnication
self.name = name #name of the Player
self.matricules = matricules #List of the two student matricules in str type
def server_response(self, s):
"""
This function is used to decode a message (bits ==> json ==> str) from the server.
Returns the message in str type.
"""
server_resp = s.recv(2048).decode()
msg = json.loads(server_resp)
return(msg)
def player_response(self, client, response):
"""
This function is used to encode and send a message (str ==> json ==> str) to the server.
"""
resp = json.dumps(response).encode('utf8')
total = 0
while total < len(resp):
sent = client.send(resp[total:])
total += sent
def sub(self):
"""
This function passes the subscription request to the game server.
"""
data = {"request": "subscribe", "port": self.game_address[1],"name": self.name, "matricules": self.matricules}
print("INFO:inscription:sent player creds: ")
print(data)
port = self.sub_address[1]
with socket.socket() as sub_sock:
sub_sock.connect(self.sub_address)
self.player_response(sub_sock, data)
print("INFO:inscription:player " + self.name + ':' + self.server_response(sub_sock)["response"])
def begin(self):
"""
This function initializes a server socket to communicate with the game server.
"""
self.player_sock = socket.socket()
self.player_sock.bind(self.game_address)
self.player_sock.listen()
def comm(self):
"""
This function handles communication requests from the game server
"""
while True:
(client, address) = self.player_sock.accept()
with client:
msg = self.server_response(client)
if msg['request'] == 'ping':
self.player_response(client, {'response': 'pong'})
print("INFO:player and server are playing at ping pong")
elif msg['request'] == 'play':
print("GAME:\nLives left: " + str(msg['lives']) + "\nErrors: " + str(msg['errors']) + "\nGame state: " + str(msg['state']))
# msg = {"response": "move","move": 15,"message": "Fun message"}
# self.player_response(client, msg)
def thread(self):
"""
This function creates a thread using the comm() fuction.
"""
threading.Thread(target = self.comm).start()
Here is my test code:
import unittest
from unittest.mock import patch, Mock
from player import Player
import socket
class Test_Player(unittest.TestCase):
@patch('socket.socket')
def test_player_response(self, mock_socket):
player = Player(("127.0.0.1", 3000), ("127.0.0.1", 8080), "TheBest", ["20269", "20269"])
mock_socket = mock_socket.return_value
player.player_response(mock_socket, {'MY QUERY'})
mock_socket.assert_called()
if __name__ == '__main__':
unittest.main()
Here is the error I get:
======================================================================
ERROR: test_player_response (__main__.Test_Player)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\basil\AppData\Local\Programs\Python\Python310\lib\unittest\mock.py", line 1369, in patched
return func(*newargs, **newkeywargs)
File "c:\Users\basil\BestAIOthello\test_player.py", line 14, in test_player_response
player.player_response(mock_socket, {'response': 'pong'})
File "c:\Users\basil\BestAIOthello\player.py", line 32, in player_response
while total < len(resp):
TypeError: '<' not supported between instances of 'MagicMock' and 'int'
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (errors=1)
I'm am new to posting questions on stackoverflow so if I was too concise or not enough feel free to tell me.