我有一个方法,它向我返回返回视图做ajax操作,如何测试它以检查正确的数据返回与否?
[HttpPost]
public ActionResult ViewPlayers(string teamName)
{
if (teamName.Contains("Все игроки"))
{
return PartialView(playerRepository.Players.ToList());
}
else
{
if (teamName != string.Empty)// send team-logo image path
{
Team findingTeam = teamRepository.Teams.First(t => t.Name.Contains(teamName));
ViewBag.TeamLogoPath = findingTeam.Path;
}
List<Player> allTeam = playerRepository.Players.Where(t => t.Team.Name.Contains(teamName)).ToList();
return PartialView(allTeam);
}
}
当我从下拉列表中选择一个团队时,我以string name
来发布,
1)如果"Все игроки"
我和所有玩家一起进入桌子
2)否则我会找到这支球队的球员。
登机测试如何将所有玩家或团队中的某些玩家返回?
答案 0 :(得分:2)
您是否尝试过简单地调用该方法并检查响应?关于MVC框架的好处是,您不需要只需要使用控制器就可以使用整个框架。堆栈中的其他组件将采用ActionResult并将其呈现为HTML。
PartialView返回一个PartialViewResult,其Model属性包含传递给PartialView
的模型。
您应该能够编写一个创建控制器,调用操作并检查结果模型的单元测试,例如:
[Test]
public void viewPlayers_Returns_One()
{
var myController=new MyController(...);
var resultView=(PartialViewResult)myController.ViewPlayers("SomeName");
var players= (List<Player>)resultView.Model;
Assert.That(players, Has.Exactly(1).Items);
}
模拟
现在棘手的部分是注入存储库。给定类似LINQ的语法,我假设playerRepository
是通过构造函数注入的EF存储库,或者是通过Players
属性公开EF实体的存储库对象。
模拟EF显示在多个SO questions和EF documentation中。
EF Core 通过其in-memory database provider使模拟变得更加容易。 EF Core与.NET运行时无关,这意味着它也可以在完整框架应用程序中使用。文档中的Testing with InMemory包含更详细的示例。还有一个示例显示了using SQLite for more advanced scenarios
懒惰,我假设存储库是实现接口的类:
public interface IPlayersRepository
{
public IQueryable<Player> Players {get;}
}
创建一个模拟类很容易,它可以接受列表,数组或播放器,并通过Players
公开它:
class MockPlayers
{
public IQueryable<Player> Players {get; private set;}
public MockPlayers(Player[] players)
{
Players=players.AsQueryable();
}
}
这很简单,甚至不需要模拟框架。之后,测试变为:
[Test]
public void viewPlayers_Returns_One()
{
var players=new[]{new Player{Name="SomeName"},new Player{Name="Other Name"}};
var mockRepo=new MockPlayers(players);
var myController=new MyController(mockRepo);
...
}
Moq对于更复杂的界面很有用。使用Moq,您可能会写:
var players = new[]{...};
var mockRepo=new Mock<IPlayersRepository>();
mockRepo.SetupGet(x => x.Players).Returns(players.AsQueryable());
EF核心
如果注入EF Core上下文,例如PlayersContext,则可以将其配置为使用内存提供程序:
//setup
var options = new DbContextOptionsBuilder<PlayersContext>()
.UseInMemoryDatabase(databaseName: "Players Test")
.Options;
using(var ctx = new PlayersContext(options))
{
ctx.Players.Add(new Player{...});
ctx.SaveChanges();
}
//Execute
using(var ctx = new PlayersContext(options))
{
var myController=new MyController(ctx);
...
}
“经典” EF
事情涉及更多,需要模拟DbSet及其一些方法。修改documentation's query scenario如下所示:
//Setup
...
var data = players.AsQueryable();
var mockSet = new Mock<DbSet<Player>>();
mockSet.As<IQueryable<Player>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Player>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Player>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Player>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<PlayerContext>();
mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);
//Execute
var myController=new MyController(mockContext.Object);
...
我是否提到EF Core可以在Full Framework应用程序中使用?