Как сделать тест модуля по Moq, ASP .NET MVC - PullRequest
0 голосов
/ 11 января 2019

У меня есть метод, он возвращает мне возвращаемое представление в операции 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);
        }
    }

enter image description here

когда я выбираю команду из выпадающего списка, я беру string name, чтобы опубликовать после этого,

1) если "Все игроки" я беру стол со всеми игроками

2) иначе я найду игрока в этой команде.

как при проверке регистрации возвращаются все игроки или отдельные игроки команды?

1 Ответ

0 голосов
/ 11 января 2019

Вы пытались просто вызвать этот метод и проверить ответ? Приятной особенностью фреймворков 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);
}

Mocking

Хитрая часть теперь вводит хранилище. Учитывая синтаксис, подобный LINQ, я предполагаю, что playerRepository - это хранилище EF, внедренное через конструктор, или объект хранилища, который предоставляет сущности EF через свойство Players.

Mocking EF показывается в нескольких SO вопросах и документации EF .

EF Core значительно облегчает имитацию с помощью провайдера базы данных в памяти . EF Core не привязан к среде выполнения .NET, что означает, что его можно использовать и в приложениях Full Framework. Тестирование с InMemory в документации содержит более подробный пример. Также есть пример, который показывает с использованием SQLite для более сложных сценариев

Будучи ленивым, я предполагаю, что репозиторий является классом, который реализует интерфейс:

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 Core

Если вы вводите контекст 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 и некоторые его методы. Адаптация сценария запроса документации будет выглядеть так:

//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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...