Refacto / Tests

This commit is contained in:
Grizouille
2025-12-13 17:06:40 +01:00
parent 1001fc3420
commit 31544bd04b
10 changed files with 475 additions and 43 deletions

View File

@@ -0,0 +1,221 @@
using FakeItEasy;
using MiniJeuxFinal.Games;
using MiniJeuxFinal.Games.PierrePapierCiseaux;
using MiniJeuxFinal.Games.PierrePapierCiseaux.Actions;
using NFluent;
using System.Reflection;
namespace MiniJeuxFinal.Test.Games.PierrePapierCiseaux
{
public class PierrePapierCiseauxGameTests
{
private readonly IPlayer _fakePlayer;
private readonly IPlayer _fakeComputer;
private readonly PierrePapierCiseauxGame _target;
public PierrePapierCiseauxGameTests()
{
_fakePlayer = A.Fake<IPlayer>();
_fakeComputer = A.Fake<IPlayer>();
_target = new PierrePapierCiseauxGame(totalRound: 3, _fakePlayer, _fakeComputer);
}
[Fact]
public void Name_Should_Return_Correct_Game_Name()
{
Check.That(_target.Name).IsEqualTo("Jeu du Pierre, Papier, Ciseaux 🧱 📄 ✂️");
}
[Fact]
public void Constructor_Should_Set_Properties_Correctly()
{
const int totalRounds = 5;
var player = A.Fake<IPlayer>();
var computer = A.Fake<IPlayer>();
var game = new PierrePapierCiseauxGame(totalRounds, player, computer);
Check.That(game).IsNotNull();
}
[Fact]
public void Start_Should_End_Game_When_Computer_Reaches_TotalRounds()
{
A.CallTo(() => _fakePlayer.Score).Returns(0);
A.CallTo(() => _fakeComputer.Score).ReturnsNextFromSequence(0, 1, 2, 3); // Atteint 3
var fakePlayerAction = A.Fake<IActionPpc>();
var fakeComputerAction = A.Fake<IActionPpc>();
A.CallTo(() => fakePlayerAction.ToWin(fakeComputerAction)).Returns(false);
A.CallTo(() => fakeComputerAction.ToWin(fakePlayerAction)).Returns(true);
A.CallTo(() => _fakePlayer.Play()).Returns(fakePlayerAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeComputerAction);
IPlayer? capturedWinner = null;
_target.GameEnded += (sender, args) => capturedWinner = args.winner;
_target.Start();
Check.That(capturedWinner).IsEqualTo(_fakeComputer);
}
[Theory]
[InlineData(true, false, true)] // Joueur gagne
[InlineData(false, true, false)] // Ordinateur gagne
[InlineData(false, false, null)] // Égalité (les deux faux)
public void Play_Should_Return_Correct_Winner(bool playerWins,
bool computerWins,
bool? expectedPlayerWins)
{
var fakePlayerAction = A.Fake<IActionPpc>();
var fakeComputerAction = A.Fake<IActionPpc>();
A.CallTo(() => fakePlayerAction.Name).Returns("Pierre");
A.CallTo(() => fakeComputerAction.Name).Returns("Ciseaux");
A.CallTo(() => fakePlayerAction.ToWin(fakeComputerAction)).Returns(playerWins);
A.CallTo(() => fakeComputerAction.ToWin(fakePlayerAction)).Returns(computerWins);
A.CallTo(() => _fakePlayer.Play()).Returns(fakePlayerAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeComputerAction);
(string, string)? capturedChoices = null;
_target.TurnStarted += (sender, args) => capturedChoices = args;
// Act - Appeler Play via réflexion car c'est privé
var playMethod = typeof(PierrePapierCiseauxGame)
.GetMethod("Play", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var result = (IPlayer?)playMethod?.Invoke(_target, null);
Check.That(capturedChoices?.Item1).IsEqualTo("Pierre");
Check.That(capturedChoices?.Item2).IsEqualTo("Ciseaux");
if (expectedPlayerWins == true)
Check.That(result).IsEqualTo(_fakePlayer);
else if (expectedPlayerWins == false)
Check.That(result).IsEqualTo(_fakeComputer);
else
Check.That(result).IsNull();
}
[Fact]
public void Start_Should_Increment_Score_When_There_Is_A_Winner()
{
A.CallTo(() => _fakePlayer.Score).ReturnsNextFromSequence(0, 1, 2); // S'arrête à 2
A.CallTo(() => _fakeComputer.Score).Returns(0);
var fakePlayerAction = A.Fake<IActionPpc>();
var fakeComputerAction = A.Fake<IActionPpc>();
A.CallTo(() => fakePlayerAction.ToWin(fakeComputerAction)).Returns(true);
A.CallTo(() => fakeComputerAction.ToWin(fakePlayerAction)).Returns(false);
A.CallTo(() => _fakePlayer.Play()).Returns(fakePlayerAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeComputerAction);
IPlayer? turnWinner = null;
_target.TurnEnded += (sender, args) => turnWinner = args.winner;
A.CallTo(() => _fakePlayer.Score).Returns(0);
A.CallTo(() => _fakeComputer.Score).Returns(0);
A.CallTo(() => _fakePlayer.IncrementScore())
.Invokes(() => A.CallTo(() => _fakePlayer.Score).Returns(1));
// Exécuter un seul tour
var playMethod = typeof(PierrePapierCiseauxGame)
.GetMethod("Play", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var winner = (IPlayer?)playMethod?.Invoke(_target, null);
if (winner != null)
winner.IncrementScore();
Check.That(winner).IsEqualTo(_fakePlayer);
A.CallTo(() => _fakePlayer.IncrementScore()).MustHaveHappenedOnceExactly();
}
[Fact]
public void Start_Should_Not_Increment_Score_On_Draw()
{
var fakePlayerAction = A.Fake<IActionPpc>();
var fakeComputerAction = A.Fake<IActionPpc>();
// Égalité : les deux retournent false
A.CallTo(() => fakePlayerAction.ToWin(fakeComputerAction)).Returns(false);
A.CallTo(() => fakeComputerAction.ToWin(fakePlayerAction)).Returns(false);
A.CallTo(() => _fakePlayer.Play()).Returns(fakePlayerAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeComputerAction);
var playMethod = typeof(PierrePapierCiseauxGame)
.GetMethod("Play", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var winner = (IPlayer?)playMethod?.Invoke(_target, null);
Check.That(winner).IsNull();
A.CallTo(() => _fakePlayer.IncrementScore()).MustNotHaveHappened();
A.CallTo(() => _fakeComputer.IncrementScore()).MustNotHaveHappened();
}
[Fact]
public void Start_Should_Raise_TurnEnded_After_Each_Round()
{
A.CallTo(() => _fakePlayer.Score).ReturnsNextFromSequence(0, 1, 2, 3); // 3 tours
A.CallTo(() => _fakeComputer.Score).Returns(0);
var fakeAction = A.Fake<IActionPpc>();
A.CallTo(() => fakeAction.ToWin(A<IActionPpc>._)).Returns(true); // Joueur gagne toujours
A.CallTo(() => _fakePlayer.Play()).Returns(fakeAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeAction);
var turnEndedCount = 0;
_target.TurnEnded += (sender, args) => turnEndedCount++;
_target.Start();
Check.That(turnEndedCount).IsEqualTo(3);
}
[Fact]
public void Start_Should_Raise_TurnStarted_Before_Each_Round()
{
A.CallTo(() => _fakePlayer.Score).ReturnsNextFromSequence(0, 1, 2, 3);
A.CallTo(() => _fakeComputer.Score).Returns(0);
var fakeAction = A.Fake<IActionPpc>();
A.CallTo(() => fakeAction.Name).Returns("TestAction");
A.CallTo(() => _fakePlayer.Play()).Returns(fakeAction);
A.CallTo(() => _fakeComputer.Play()).Returns(fakeAction);
var turnStartedCount = 0;
_target.TurnStarted += (sender, args) => turnStartedCount++;
_target.Start();
Check.That(turnStartedCount).IsEqualTo(3);
}
[Fact]
public void Play_Should_Throw_When_Action_Is_Not_IActionPpc()
{
var invalidAction = A.Fake<IAction>(); // Pas IActionPpc
A.CallTo(() => _fakePlayer.Play()).Returns(invalidAction);
A.CallTo(() => _fakeComputer.Play()).Returns(A.Fake<IActionPpc>());
var playMethod = typeof(PierrePapierCiseauxGame)
.GetMethod("Play", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
Check.ThatCode(() => playMethod?.Invoke(_target, null))
.Throws<TargetInvocationException>();
}
}
}

View File

@@ -1,13 +0,0 @@
using NFluent;
namespace MiniJeuxFinal.Test;
public class PpcTest
{
[Fact]
public void Test1()
{
var i = 1;
Check.That(i).IsEqualTo(1);
}
}

View File

@@ -0,0 +1,157 @@
using FakeItEasy;
using MiniJeuxFinal.Games;
using MiniJeuxFinal.Ui;
using MiniJeuxFinal.Wrappers;
using NFluent;
namespace MiniJeuxFinal.Test.Ui
{
public class GameRunnerConsoleTests
{
private readonly IGame _fakeGame;
private readonly IConsole _fakeConsole;
private readonly GameRunnerConsole _target;
public GameRunnerConsoleTests()
{
_fakeGame = A.Fake<IGame>();
_fakeConsole = A.Fake<IConsole>();
_target = new GameRunnerConsole(_fakeConsole, _fakeGame);
}
// Dispose pour nettoyer les tests
public void Dispose() => _target.Dispose();
[Fact]
public void Constructor_Should_Subscribe_To_Game_Events()
{
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "add_TurnStarted")
.MustHaveHappenedOnceExactly();
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "add_TurnEnded")
.MustHaveHappenedOnceExactly();
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "add_GameEnded")
.MustHaveHappenedOnceExactly();
}
[Fact]
public void Dispose_Should_Unsubscribe_From_Game_Events()
{
_target.Dispose();
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "remove_TurnStarted")
.MustHaveHappenedOnceExactly();
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "remove_TurnEnded")
.MustHaveHappenedOnceExactly();
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "remove_GameEnded")
.MustHaveHappenedOnceExactly();
}
[Fact]
public void Run_Should_Display_GameName_Then_Start_Game()
{
const string gameName = "PIERRE-PAPIER-CISEAUX";
A.CallTo(() => _fakeGame.Name).Returns(gameName);
_target.Run();
A.CallTo(() => _fakeConsole.WriteLine(gameName)).MustHaveHappenedOnceExactly();
A.CallTo(() => _fakeConsole.WriteLine()).MustHaveHappenedOnceExactly();
A.CallTo(() => _fakeGame.Start()).MustHaveHappenedOnceExactly();
var calls = Fake.GetCalls(_fakeConsole).ToList();
Check.That(calls[0].Arguments[0]).IsEqualTo(gameName);
Check.That(calls[1].Arguments).IsEmpty(); // WriteLine() sans paramètre
}
[Fact]
public void OnTurnStarted_Should_Display_Both_Choices()
{
_fakeGame.TurnStarted += Raise.FreeForm.With(null, ("1", "2"));
A.CallTo(() => _fakeConsole.WriteLine($"Tu joues : 1"))
.MustHaveHappenedOnceExactly();
A.CallTo(() => _fakeConsole.WriteLine($"L'ordinateur joue : 2"))
.MustHaveHappenedOnceExactly();
}
[Theory]
[InlineData(null, "Égalité !")] // winner = null
[InlineData("Joueur1", "Joueur1 gagne la manche")] // winner = Joueur1
public void OnTurnEnded_Should_Clear_And_Display_Results(string? winnerName, string expectedMessage)
{
// Arrange
IPlayer? fakeWinner = winnerName != null ? A.Fake<IPlayer>() : null;
if (fakeWinner != null)
A.CallTo(() => fakeWinner.Name).Returns(winnerName);
var fakePlayer1 = A.Fake<IPlayer>();
var fakePlayer2 = A.Fake<IPlayer>();
A.CallTo(() => fakePlayer1.ToString()).Returns("Joueur1 (3 pts)");
A.CallTo(() => fakePlayer2.ToString()).Returns("Ordinateur (1 pt)");
var players = new[] { fakePlayer1, fakePlayer2 };
var eventArgs = (fakeWinner, players);
// Capturer le handler
EventHandler<(IPlayer?, IPlayer[])>? handler = null;
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "add_TurnEnded")
.Invokes(call => handler = (EventHandler<(IPlayer?, IPlayer[])>)call.Arguments[0]);
var target2 = new GameRunnerConsole(_fakeConsole, _fakeGame);
handler?.Invoke(this, eventArgs);
A.CallTo(() => _fakeConsole.Clear())
.MustHaveHappenedOnceExactly()
.Then(A.CallTo(() => _fakeConsole.WriteLine(expectedMessage))
.MustHaveHappenedOnceExactly())
.Then(A.CallTo(() => _fakeConsole.WriteLine(A<string>.That.Contains("Score :")))
.MustHaveHappenedOnceExactly());
target2.Dispose();
}
[Fact]
public void OnGameEnded_Should_Display_Winner_And_Final_Score()
{
var fakeWinner = A.Fake<IPlayer>();
var fakeLoser = A.Fake<IPlayer>();
A.CallTo(() => fakeWinner.Name).Returns("Joueur1");
A.CallTo(() => fakeWinner.Score).Returns(5);
A.CallTo(() => fakeLoser.Name).Returns("Ordinateur");
A.CallTo(() => fakeLoser.Score).Returns(2);
var players = new[] { fakeWinner, fakeLoser };
var eventArgs = (fakeWinner, players);
EventHandler<(IPlayer, IPlayer[])>? handler = null;
A.CallTo(_fakeGame)
.Where(call => call.Method.Name == "add_GameEnded")
.Invokes(call => handler = (EventHandler<(IPlayer, IPlayer[])>)call.Arguments[0]);
var target2 = new GameRunnerConsole(_fakeConsole, _fakeGame);
handler?.Invoke(this, eventArgs);
A.CallTo(() => _fakeConsole.WriteLine("Joueur1 A GAGNÉ ! 🎉🎉🎉"))
.MustHaveHappenedOnceExactly();
A.CallTo(() => _fakeConsole.WriteLine("Score final : 5 - 2"))
.MustHaveHappenedOnceExactly();
target2.Dispose();
}
}
}