Как провести модульное тестирование метода в Sitecore MVC с тесно связанной зависимостью от двух разных контекстов Sitecore?

К сожалению, мне приходится писать модульные тесты для устаревшей базы кода Sitecore MVC, где вызываются два разных контекста Sitecore. Я понимаю, что это относится к интеграционному тестированию, но у меня нет возможности обучать своих руководителей проектов на этом фронте. Поэтому я решил использовать FakeDb для эмуляции экземпляра Sitecore и NSubstitute для замены внедренных зависимостей (не могу использовать любые API-фреймворки Profilier, такие как MS Fakes, TypeMock и т. д., из-за ограничений бюджета). ). Я предоставляю код ниже:

Метод для модульного тестирования

 public bool DubiousMethod()
 {
    // This HttpContext call is pain area 1. This gets resolved when i call it using ItemContextSwitcher in Unit Tests.
    string currentUrl = HttpContext.Current.Request.RawUrl; 

   // This Sitecore Context call to Site Name is pain area 2. This gets resolved when Unit Tests are run under SiteContextSwitcher.
    string siteName = Sitecore.Context.Site.Name;

    return true/False;
 }

Метод модульного тестирования

[Fact]

public void DubiousMethodUT()
{
 // create a fake site context            
        var fakeSite = new Sitecore.FakeDb.Sites.FakeSiteContext(
          new Sitecore.Collections.StringDictionary
           {
              { "name", "website" }, { "database", "web" }, { "rootPath", "/sitecore/content/home" },
              { "contentStartItem", "home"}, {"hostName","https://www.myorignalsiteurl.com"}                 

           });

 using (new Sitecore.Sites.SiteContextSwitcher(fakeSite))
        {                           
            //DubiousClassObject.DubiousMethod(home) // When Debugging after uncommenting this line i get correct value in **Sitecore.Context.Site.Name**
            using (Sitecore.FakeDb.Db db = new Sitecore.FakeDb.Db
                 {

                   new Sitecore.FakeDb.DbItem("home") { { "Title", "Welcome!" } ,

                   new Sitecore.FakeDb.DbItem("blogs") }
                  })

            {

                Sitecore.Data.Items.Item home = db.GetItem("/sitecore/content/home");
                //bool abc = confBlogUT.IsBlogItem(home);
                using (new ContextItemSwitcher(home))
                {
                    string siteName = Sitecore.Context.Site.Name;
                    var urlOptions = new Sitecore.Links.UrlOptions();
                    urlOptions.AlwaysIncludeServerUrl = true;
                    var pageUrl = Sitecore.Links.LinkManager.GetItemUrl(Sitecore.Context.Item, urlOptions);
                    HttpContext.Current = new HttpContext(new HttpRequest("", pageUrl.Substring(3), ""), new HttpResponse(new StringWriter()));



                    Assert.False(DubiousClassObject.DubiousMethod(home); //When Debugging after commenting above DubiousMethodCall i get correct value for **HttpContext.Current.Request.RawUrl**
                }
            }
        }
    }

Как вы можете заметить, когда я пытаюсь вызвать метод из FakSiteContext, я получаю правильное значение для Sitecore.Context.Site.Name, однако мой код ломается, когда HttpContext.Current.Request. RawUrl вызывается в методе. Противоположное происходит, когда я вызываю метод из контекста ContextItemSwitcher(FakeItem). До сих пор мне не удалось найти способ объединить оба контекста (что, я считаю, невозможно в Sitecore). Может ли кто-нибудь предложить, запускаю ли я свои модульные тесты в всеобъемлющем контексте, где я могу контролировать переменные fakeSite, а также переменные контекста FakeItem, а также расширения любых других вызовов контекста Sitecore?

Любая помощь будет оценена по достоинству.


person Nitin shukla    schedule 04.11.2019    source источник


Ответы (1)


Я бы порекомендовал взглянуть на модульное тестирование в Sitecore Статья вроде бы то, что нужно.

Короче говоря, вам нужно будет внести несколько изменений в свой код, чтобы сделать его пригодным для тестирования:

1) Заменить статический HttpContext на абстрактный HttpContextBase (импл. HttpContextWrapper), чтобы все можно было устроить - DubiousMethod получает перегрузку, которая принимает DubiousMethod(HttpContextBase httpContext).

2) Что касается данных контекста Sitecore — они имеют семантику с привязкой Sitecore.Caching.ItemsContext (как упоминалось в статье), поэтому вы можете очищать коллекцию до/после каждого теста, чтобы получить своего рода изоляцию между тестами.

В качестве альтернативы вы можете испечь аналогичную оболочку для Sitecore.Context, как команда ASP.NET сделала для HttpContext -> HttpContextBase & impl HttpContextWrapper.

person Nikolay Mitikov    schedule 21.01.2020