Unity Test wyrzuca wyjątek TypeInitializationException w czasie uruchamiania

0

Problem wynikł w trakcie przerabiania książki "Asp.NET MVC 5 Zaawansowane Programowanie" rozdział 7. Zależało mi na czasie i to zignorowałem, teraz jednak wracam do problemu i dalej nie wiem jak to rozwiązać.
Rozpisałem kod testujący pracę kontrolera wywołującego dane zwracane do widoku. Wyjątek następuje jedynie przy uruchamianiu testu, sama aplikacja działa bez problemu. Poniżej szczegóły:

Model (4 oddzielne pliki):

 

 public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }

public interface IProductRepository
    {
        IEnumerable<Product> Products { get; }
    }

 public class PagingInfo
    {
        public int TotalItems { get; set; }
        public int ItemsPerPage { get; set; }
        public int CurrentPage { get; set; }

        public int TotalPages
        {
            get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
        }
    }

 public class ProductsListViewModel
    {
        public IEnumerable<Product> Products { get; set; }
        public PagingInfo PagingInfo { get; set; }
        public string CurrentCategory { get; set; }
    }

Kontroler:

 
        private IProductRepository repository;
        public int PageSize = 4;
        

        public ProductController(IProductRepository productRepository)
        {
            this.repository = productRepository;
        }

        public ViewResult List( int page = 1)
        {

            ProductsListViewModel model = new ProductsListViewModel
            {
                Products = repository.Products
                .OrderBy(p => p.ProductID)
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = PageSize,
                    TotalItems = repository.Products.Count()
                }
            };

            return View(model);

        }

Test:

 
   [TestMethod]
        public void Can_Paginate()
        {
            //przygotowanie
            Mock<IProductRepository> mock = new Mock<IProductRepository>();
            mock.Setup(m => m.Products).Returns(new Product[]
            {
                new Product {ProductID = 1, Name = "P1" },
                new Product {ProductID = 2, Name = "P2" },
                new Product {ProductID = 3, Name = "P3" },
                new Product {ProductID = 4, Name = "P4" },
                new Product {ProductID = 5, Name = "P5" }
            });

            ProductController controller = new ProductController(mock.Object);
            controller.PageSize = 3;

            //działanie
            ProductsListViewModel result = (ProductsListViewModel)controller.List(2).Model;

            //aseracje
            Product[] prodArray = result.Products.ToArray();
            Assert.IsTrue(prodArray.Length == 2);
            Assert.AreEqual(prodArray[0].Name, "P4");
            Assert.AreEqual(prodArray[1].Name, "P5");
        }

Komunikat błędu:

Test Name:	Can_Paginate
Test FullName:	SportsStore.UnitTests.UnitTest1.Can_Paginate
Test Source:	D:\visual studio projekty\SportsStore\SportsStore.UnitTests\UnitTest1.cs : line 22
Test Outcome:	Failed
Test Duration:	0:00:00,4558873

Result StackTrace:	
at System.Web.Mvc.BuildManagerViewEngine..ctor(IViewPageActivator viewPageActivator, IResolver`1 activatorResolver, IDependencyResolver dependencyResolver, VirtualPathProvider pathProvider)
   at System.Web.Mvc.WebFormViewEngine..ctor(IViewPageActivator viewPageActivator)
   at System.Web.Mvc.WebFormViewEngine..ctor()
   at System.Web.Mvc.ViewEngines..cctor()
 --- End of inner exception stack trace ---
    at System.Web.Mvc.ViewEngines.get_Engines()
   at System.Web.Mvc.Controller.View(String viewName, String masterName, Object model)
   at SportsStore.WebUI.Controllers.ProductController.List(String category, Int32 page) in D:\visual studio projekty\SportsStore\SportsStore.WebUI\Controllers\ProductController.cs:line 30
   at SportsStore.UnitTests.UnitTest1.Can_Paginate() in D:\visual studio projekty\SportsStore\SportsStore.UnitTests\UnitTest1.cs:line 33
Result Message:	
Test method SportsStore.UnitTests.UnitTest1.Can_Paginate threw exception: 
System.TypeInitializationException: The type initializer for 'System.Web.Mvc.ViewEngines' threw an exception. ---> System.MissingMethodException: Method not found: 'Void System.Web.WebPages.FileExistenceCache..ctor(System.Func`1<System.Web.Hosting.VirtualPathProvider>, Int32)'.

Wygląda na to, że problem następuje w momencie kompilowania kodu wywołującego metodę List. Jednak nie wiem czemu, wywala to cały test. Sama aplikacja działa bez problemu, IDE zaś nie podkreśla mi żadnych błędów składniowych.

1

Jedyny podobny przypadek jaki znalazłem to http://stackoverflow.com/questions/23491769/missingmethodexception-fileexistencecache-with-mvc-5-1
Skopiowałem twój kod i próbowałem ten błąd powtórzyć ale za cholerę mi się to nie udało, a próbowałem na różnych wersjach System.Web.Mvc.dll 5.0.0, 5.1.0, 5.2.3.0. I tak samo użyłem(o ile dobrze wywnioskowałem z kodu) VisualStudio.TestTools oraz Moq. Może masz jakiś przykładowy projekt na którym to się tak wywala? :)

0

W tej książce jest trochę takich byków i co jakiś czas na nie trafiam. Właśnie sam ją przerabiam :)

W Unit Teście tam gdzie masz "działanie", to w miejsce

ProductsListViewModel result = (ProductsListViewModel)controller.List(2).Model;


wstaw to:
<code class="c#">
ProductsListViewModel result = (ProductsListViewModel)controller.List(null, 2).Model;
0

A nie, wróć, sory. Miałem w tym miejscu też problem, ale na późniejszym etapie, gdzie on poszerzył metodę List o parametr category, a potem go w Unit Teście nie uwzględnił i z tego wynikał błąd.

Swoją drogą miałem też na początku problemy z wersjami pakietów, które on polecił instalować, a które potem okazały się być niezgodne.

0

@DibbyDum Koleś w książce używa konkretnych wersji bibliotek:

Moq - wersja 4.1.1309.1617
Aspnet.Mvc - wersja 5.0.0

Specjalnie po to aby nie było błędów:P

Wymieniłem w projekcie testowym Moq'a na nowszego ale też nie pomogło.

Edit:
@DibbyDum Nakierowałeś mnie. Okazało się że jak tworzyłem projekty domeny, testów i na koniec web'a to biblioteki Mvc były wgrane:
5.0.0 do testów
5.2.3 do weba

Zaktualizowałem i działa :) Dzięki !

0

@EroSanin
Dobrze że się udało. Nie wiem na jakim etapie rozdziału jesteś, ale u mnie problemy z pakietami pojawiły się po tym, jak trzeba było w pewnym momencie doinstalować EntityFramework. Jeśli na coś takiego trafisz, to znowu może być zabawa z pakietami i plikiem Web.config. Z tego co pamiętam, to Ninject miał potem jakieś zastrzeżenia co do wersji MVC i dodatkowo Razor też miał podobnie. Używam VS 2013.

1 użytkowników online, w tym zalogowanych: 0, gości: 1