Проблем с MOQ - подиграваният клас връща неправилни данни

И така, използвам moq за тестване, но се натъкнах на проблем, който ми пречи да се подигравам правилно, поне така мисля. Това е моят клас хранилище:

public interface IAccountsRepository
    {
        IQueryable<Account> Accounts { get; }
        IQueryable<Account> AccountsPaged(int pageSize, int selectedPage);
    }

Това е една от реализациите (фалшиви):

public class FakeAccountsRepository : IAccountsRepository
    {
        private static readonly IQueryable<Account> FakeAccounts = new List<Account> {
        new Account {RegistrationEmail = "[email protected]"},
        new Account {RegistrationEmail = "[email protected]"},
        new Account {RegistrationEmail = "[email protected]"},
        new Account {RegistrationEmail = "[email protected]"},
        new Account {RegistrationEmail = "[email protected]"}
        }.AsQueryable();

        public IQueryable<Account> Accounts
        {
            get { return FakeAccounts; }
        }

        public IQueryable<Account> AccountsPaged(int pageSize, int selectedPage)
        {
            return FakeAccounts.Skip((selectedPage - 1)*pageSize).Take(pageSize).AsQueryable();
        }
    }

Това е дефиниция на контролер, която работи перфектно с реална страница и фалшиви или sql данни (IoC) в истинска уеб страница:

public class AccountsController : Controller
    {
        private IAccountsRepository _accountsRepository;
        public int PageSize = 3;

        public AccountsController(IAccountsRepository accountsRepository)
        {
            this._accountsRepository = accountsRepository;
        }

        public ViewResult List(int selectedPage)
        {
               return View(_accountsRepository.AccountsPaged(PageSize, selectedPage).ToList());
        }
    }

Това е moq метод:

static IAccountsRepository MockAccountsRepository(params Account[] accs)
        {
            // Generate an implementor of IAccountsRepository at runtime using Moq
            var mockProductsRepos = new Moq.Mock<IAccountsRepository>();
            mockProductsRepos.Setup(x => x.Accounts).Returns(accs.AsQueryable());
            return mockProductsRepos.Object;
        }

работи добре с тази реализация на страниране на списък:

public ViewResult List(int selectedPage)
        {
            return View(_accountsRepository.Accounts.Skip((selectedPage - 1) * PageSize).Take(PageSize).ToList());

        }

но се проваля при използване на това:

public ViewResult List(int selectedPage)
        {
            return View(_accountsRepository.AccountsPaged(PageSize, selectedPage).ToList());
        }

Без промяна на теста и промяна само на внедряването на List (извършване на страниране само на .Accounts) всичко работи, но когато се опитам да използвам метода AccountsPaged, той не връща никакви елементи. При реална употреба, на уеб страница, работи и в двете посоки.

Моля за съвет, благодаря.

РЕДАКТИРАНЕ: Ако направя това:

mockProductsRepos.Setup(x => x.AccountsPaged(Moq.It.IsAny<int>(), Moq.It.IsAny<int>())).Returns(accs.AsQueryable());

Получавам 5 върнати артикула вместо 2.


person BuzzBubba    schedule 08.08.2009    source източник


Отговори (2)


Не сте настроили метода AccountsPaged във вашия макет

РЕДАКТИРАНЕ: След като настроихте AccountsPaged, не сте го настроили правилно. Ето как да го настроите правилно:

mockProductsRepos
   .Setup(x => x.AccountsPaged(Moq.It.IsAny<int>(), Moq.It.IsAny<int>()))
   .Returns( (int pageSize, int selectedPage) => accs.Skip((selectedPage-1)*pageSize).Take(pageSize).AsQueryable() );
person Michaël Larouche    schedule 08.08.2009
comment
Настроих го сега, както добавих към публикацията по-горе, но ми дава 5 елемента вместо 2 - което би се очаквало, ако извикването .List() работи правилно. Не знам как може и защо връща пълни членове? Има ли начин за стъпка по стъпка отстраняване на грешки в настройката на moq? - person BuzzBubba; 09.08.2009

Не анализирах кода ви в дълбочина, но общото правило е - когато се съмнявате относно коректността на фалшивата, използвайте стриктна подигравка, за да изчистите всички липсващи очаквания:

var mock = new Mock(MockBehavior.Strict);

по този начин ще получите изрични индикации за всички неочаквани повиквания, издадени от SUT, които сте забравили да осмиете.

person Addys    schedule 10.08.2009