在 Visual Studio 2010 中为'Rock, Paper and Scissors'游戏编写单元测试



我是编程、面向对象和单元测试的新手,所以请原谅我的知识不足。

作为我的石头剪刀布游戏的一部分,我有一个抽象的超类(武器),它在VB中有子类(石头剪刀布)。净:

    Public MustInherit Class Weapons
         Public MustOverride Function compareTo(ByVal Weapons As Object) As Integer
    End Class
    Public Class Paper
        Inherits Weapons
        Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
            If TypeOf Weapons Is Paper Then
                Return 0
            ElseIf TypeOf Weapons Is Rock Then
                Return 1
            Else
                Return -1
            End If
        End Function
    End Class
    Public Class Rock
        Inherits Weapons
        Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
            If TypeOf Weapons Is Rock Then
                Return 0
            ElseIf TypeOf Weapons Is Scissors Then
                Return 1
            Else
                Return -1
            End If
        End Function
    End Class
    Public Class Scissors
        Inherits Weapons
        Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
            If TypeOf Weapons Is Scissors Then
                Return 0
            ElseIf TypeOf Weapons Is Paper Then
                Return 1
            Else
                Return -1
            End If
        End Function
    End Class

也有一个超类Player,它有子类(PlayerComputerRandomPlayerHumanPlayerPlayerComputerTactical),如:

    Imports RockPaperScissors.Weapons
Public Class Player
    Private pName As String
    Private pNumberOfGamesWon As String
    Public pWeapon As Weapons
    Property Name() As String
        Get
            Return pName
        End Get
        Set(ByVal value As String)
            pName = value
        End Set
    End Property
    Property NumberOfGamesWon As String
        Get
            Return pNumberOfGamesWon
        End Get
        Set(ByVal value As String)
            pNumberOfGamesWon = value
        End Set
    End Property
    Property getWeapon As Weapons
        Get
            Return pWeapon
        End Get
        Set(ByVal value As Weapons)
            pWeapon = value
        End Set
    End Property
    Public Sub pickWeapon(ByVal WeaponType As String)
        If WeaponType = "Rock" Then
            pWeapon = New Rock()
        ElseIf WeaponType = "Paper" Then
            pWeapon = New Paper()
        Else
            pWeapon = New Scissors()
        End If
    End Sub
End Class

    Imports RockPaperScissors.Weapons
Public Class PlayerComputerRandom
    Inherits Player
    Private Enum weaponsList
        Rock
        Paper
        Scissors
    End Enum
    Public Overloads Sub pickWeapon()
        Dim randomChoice = New Random()
        Dim CompChoice As Integer = randomChoice.Next(0, [Enum].GetValues(GetType(weaponsList)).Length)
        If CompChoice = "0" Then
            pWeapon = New Rock()
        ElseIf CompChoice = "1" Then
            pWeapon = New Paper()
        Else
            pWeapon = New Scissors()
        End If

    End Sub
End Class

 Public Class PlayerComputerTactical
    Inherits Player
    Private plastMove As String
    Property lastMove() As String
        Get
            Return plastMove
        End Get
        Set(ByVal value As String)
            plastMove = value
        End Set
    End Property
    Public Overloads Sub pickWeapon()
        ' Add tactical player functionality
    End Sub

End Class

     Public Class PlayerHumanPlayer
        Inherits Player
    End Class

我有一个GameForm类,它实例化对象并执行前端使用的各种其他逻辑,如下所示:

    Public Class GameForm
    Private Sub btnRock_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRock.Click
        findWinner("HumanPlayer", "Rock", "RandomComputer")
    End Sub
    Private Sub btnPaper_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPaper.Click
        findWinner("HumanPlayer", "Paper", "RandomComputer")
    End Sub

    Private Sub btnScissors_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnScissors.Click
        findWinner("HumanPlayer", "Scissors", "RandomComputer")
    End Sub
    Public Sub findWinner(ByVal p1name As String, ByVal p1WeaponSelected As String, ByVal p2Name As String)
        Dim player1 = New PlayerHumanPlayer()
        Dim player2 = New PlayerComputerRandom()
        player1.Name = p1name
        player1.pickWeapon(p1WeaponSelected)  ' Should I be using the Rock Class???
        player2.Name = p2Name
        player2.pickWeapon()
        Dim winner As Integer = player1.getWeapon().compareTo(player2.getWeapon())
        Select Case winner
            Case 1
                txtGameStatus.Text = player1.Name() + " wins!"
            Case -1
                txtGameStatus.Text = player2.Name() + " wins!"
            Case 0
                txtGameStatus.Text = "Draw!"
        End Select
    End Sub
End Class

我需要使用visual studio 2010编写单元测试。因为我从来没有这样做过,所以我不知道我可以包括哪些单元测试(除了stand - add/subtract示例)。有人可以提供一些单元测试开始。它会给我一个起点。

任何帮助都将是非常感激的。

提前致谢

我的第一个技巧是将所有方法更改为返回值的函数,这是您想要进行单元测试的方法。这样做将确保您可以在单元测试中使用该函数。

我可以为你的结构提供帮助,但恐怕我不会为你做单元测试!

我将向您展示一个解决方案中的单元测试示例,它可能与您的解决方案无关,但结构仍然存在。首先,我有函数(添加),我想测试,并在一个单元测试项目,我有测试。

测试函数

Public Function Add(value1 As Int32, value2 As Int32)
    answer = value1 + value2
    Return answer
End Function

这是我在单元测试类

中使用的单元测试
<TestMethod()> _
Public Sub AddTest()
    Dim target As Form1 = New Form1()
    Dim value1 As Int32 = 10
    Dim value2 As Int32 = 35
    Dim actual As Int32 = 45
    Dim result As Int32 = target.Add(value1, value2)
    Assert.AreEqual(result, actual)
End Sub

试着给你一个例子来说明如何构建这个:

首先,代替这个:

Public Overloads Sub pickWeapon()
   ' Logic...         
End Sub

你可能想这样做:

 Public Overloads Function pickWeapon() as Weapons
    Dim selectedWeapon as Weapons = Nothing;
    // logic to set weapon here
    return selectedWeapon;
End Sub

现在你可以从UnitTest中调用它,并确保它返回的对象是一个有效的武器,例如(不一定是最有用的测试,但希望,你明白了!:))。

如果您以类似的方式重构方法findWinner(),您可以测试该方法的逻辑是否找到正确的赢家。

但是请注意,您应该将寻找赢家的逻辑与选择武器的逻辑分开。也就是说,您应该在该方法之外创建玩家,并将它们传递给findWinner()。这将允许你传递某些选项(武器),并检查你是否获得了预期的结果。你现在不能这样做,因为"player2"将使用的武器是由findWinner()内部随机选择的。

首先修改它,使其具有类似于以下的签名:

' Takes two players in, and returns the name of the winner
Public Sub findWinner(ByVal humanPlayer As PlayerHumanPlayer, 
                      ByVal computerPlayer As PlayerComputerRandom) As String

一个(非常简单的)测试,假设您已经重写了代码以适合以下内容:

<TestMethod()> _
Public Sub ShouldReturnPlayer1AsWinner()
    Dim player1 = New PlayerHumanPlayer("Human name", New Scissors())
    Dim player2 = New PlayerComputerRandom("Computer", New Rock())
    Dim result As String = findWinner(player1, player2)
    Assert.AreEqual(result, "Computer")
End Sub

同样,这可能不是最好的测试,但它应该给你一个想法,并帮助你开始。

旁注:我将超类命名为Weapon,而不是Weapons。你可以这么想:你可以有许多不同的实例,它们可以是不同的武器(如纸、剪刀等),但它们仍然是一个单一的武器。