[英]Learning unit testing in C#
因此,我尝试使用我在网上找到的示例项目来学习 C# 中的单元测试。 该项目在这里。
这是我第一次进行单元测试,所以我仍在学习并且遇到了一些错误。 这是我要测试的代码:
IRoosterService
:
namespace MoqBusiness
{
public interface IRoosterService
{
IList<Player> GetPlayersFromRepo();
}
}
RoosterService
:
namespace MoqBusiness
{
public class RoosterService : IRoosterService
{
private readonly IPlayersRepo _players;
public RoosterService(IPlayersRepo players)
{
_players = players;
}
public IList<Player> GetPlayersFromRepo()
{
return _players.GetPlayerList();
}
}
}
IPlayersRepo
:
namespace MoqDataRepos
{
public interface IPlayersRepo
{
IList<Player> GetPlayerList();
}
}
PlayersRepo
:
namespace MoqDataRepos
{
public class PlayersRepo:IPlayersRepo
{
public IList<Player> GetPlayerList()
{
var playerList = new List<Player> {
new Player { Name = "Swaroop", Age = 28 ,PlayersClub = new Club{ ClubName = "Manchester United",CountryName = "GB",Position = 7} },
new Player { Name = "Seema", Age = 30 ,PlayersClub = new Club{ ClubName = "Manchester United",CountryName = "GB",Position = 7}},
new Player { Name = "Jay", Age = 35 ,PlayersClub = new Club{ ClubName = "Arsenal",CountryName = "GB",Position = 4}},
new Player { Name = "Don", Age = 30 ,PlayersClub = new Club{ ClubName = "Manchester City",CountryName = "GB",Position = 1}}
};
return playerList;
}
}
}
因此,我尝试使用 Moq 和 XUnit 开始测试这个RoosterService
class。
我的想法是我正在测试GetPlayersFromRepo
方法是否返回PlayersRepo
- GetPlayerList
中的玩家,所以我会首先使用GetPlayersFromRepo
方法,然后调用PlayersRepo
- GetPlayerList
方法并比较两者以查看它们是否相等。
这是我的测试代码:
namespace MoqTests
{
public class RoosterServiceTests
{
private readonly RoosterService _service;
private readonly Mock<IPlayersRepo> playersRepoMock = new Mock<IPlayersRepo>();
public RoosterServiceTests()
{
_service = new RoosterService(playersRepoMock.Object);
}
[Fact]
public void GetPlayersFromRepo_ShouldReturnPlayers()
{
//Arrange
var expected = playersRepoMock.Setup(p => p.GetPlayerList()).Returns(new List<Player>());
//Act
var players = _service.GetPlayersFromRepo();
//Assert
Assert.Equal(players, expected);
}
}
}
但是,这不起作用,因为会出现以下错误消息
参数 2:无法从“Moq.Language.Flow.IReturnsResult<MoqDataRepos.IPlayersRepo>”转换为“System.Collections.Generic.IEnumerable<MoqDataModel.Player>”
我不明白为什么会发生这种情况,因为这两种方法都返回一个列表,所以不确定为什么会发生此错误。 因为这是我的第一次测试,我想我也可能设置错了吗? 任何建议表示赞赏。
首先,您不需要playersRepoMock.Setup
的返回值,它返回的内容可能不是您所期望的。
其次,在你的单元测试中,你会有这样的东西:
[Fact]
public void GetPlayersFromRepo_ShouldReturnPlayers()
{
//Arrange
var expected = new List<Player>();
playersRepoMock.Setup(p => p.GetPlayerList()).Returns(expected);
//Act
var players = _service.GetPlayersFromRepo();
//Assert
Assert.Equal(expected, players);
}
我建议执行以下操作:
expected
的和actual
的前缀来帮助提高易读性sut
)作为正在测试的 object 的变量名Verify
)[Fact]
public void GivenAPlayerListWithASinglePlayer_WhenICallGetPlayersFromRepo_ThenItReturnsTheReposCollection()
{
//Arrange
var club = new Club { ClubName = "Manchester United", CountryName = "GB", Position = 7 };
var player = new Player { Name = "Swaroop", Age = 28 ,PlayersClub = club };
var expectedPlayers = new List<Player> { player };
var playersRepoMock = new Mock<IPlayersRepo>();
playersRepoMock
.Setup(p => p.GetPlayerList())
.Returns(expectedPlayers);
var sut = new RoosterService(playersRepoMock.Object);
//Act
var actualPlayers = sut.GetPlayersFromRepo();
//Assert
playersRepoMock.Verify(p => p.GetPlayerList(), Times.Once);
Assert.Equal(expectedPlayers, actualPlayers);
}
根据您想要测试代码的防御性程度,您可以拥有以下测试用例:
PS:如果您需要对集合执行断言,那么请更喜欢使用FluentAssertions
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.