Sitecore.FakeDb icon indicating copy to clipboard operation
Sitecore.FakeDb copied to clipboard

FakeDb does not have GetItem(string path, Language lang) overload

Open NitinShuklaML opened this issue 5 years ago • 4 comments

Hi,

Thanks for such a great framework for unit testing Sitecore. However i am in a bit of a bind as i am writing unit tests for a legacy framework wherein there are several calls to the Sitecore Database with item path and Language overloads. But as i checked in FakeDb's source code there is no receiver for a call of above mentioned type in FakeDb.

Below is a rudimentary sample of code under test:

public Item ReturnItemFromPathandLanguage(string path, string language)
{
    // This is just a representation of the code constraint i cannot remove this line
       Language lan = Language.Parse(language);
       var db = Sitecore.Context.Database;
       return db.GetItem(path, lan);
}

The above code works really well in the original Website code and has several calls in other classes as well.

Below is my Unit Test:

[Fact]

public void ReturnItemFromPathandLanguageUT()
{
            // create a fake site context
            var fakeSite = new Sitecore.FakeDb.Sites.FakeSiteContext(
              new Sitecore.Collections.StringDictionary
                {
                  { "name", "website" }, { "database", "web" }
                });

            // switch the context site
            using (new Sitecore.Sites.SiteContextSwitcher(fakeSite))
            {
                using (var db = new Db
                {
                new DbItem("Home") { { "Title", "Welcome!" }, { "en", "Welcome" }}                
            })
                        
                {
                    
                   var home = db.GetItem("/sitecore/content/home");
                   SomeClass obj = new SomeClass();
                    var actual = obj.ReturnItemFromPathandLanguageUT("home.Paths.FullPath","en");

                    // var expected = home;
                    // Assert
                    //Assert.Equal(actual, expected);
                }

            }

}

My code always returns null in the ReturnItemFromPathandLanguage method where the call is made to Sitecore Database with string and Language overloads. Can you look into this?

Regards, Nitin

NitinShuklaML avatar Jan 14 '20 07:01 NitinShuklaML

@NitinShuklaML, thanks for using FakeDb.

The issue is in the home item path. You pass the text constant "home.Paths.FullPath" instead of the actual value ;)

Just remove the quotes and test will pass:

var actual = obj.ReturnItemFromPathandLanguageUT(home.Paths.FullPath, "en");

sshushliapin avatar Jan 14 '20 11:01 sshushliapin

@sshushliapin ,

Apologies for not being able to frame my question correctly. I would like to politely point out that home.Paths.FullPath is not the issue here. I wrote it that way for the sake of this question. In actual unit tests we use hard coded paths for the fake items made in-memory.

My doubt portends to the actual overload call of GetItem method in Sitecore Kernel. If you navigate to the the definition you would find that Sitecore.Kernel has below mentioned overload:

GetItem(string path , Language language)

So i have a class method that calls the above mentioned overload to fetch an item. However when i write the unit test i make Fake Items using DbItem. While setting up the unit tests i have made the relevant item in the fake Content Tree. Now when i debug the unit test for below code:

public Item ReturnItemFromPathandLanguage(string path, string language)
{
    // This is just a representation of the code constraint i cannot remove this line
       Language lan = Language.Parse(language);
       var db = Sitecore.Context.Database;
       return db.GetItem(path, lan); // Check the overload for this method
}

In the context of Unit tests GetItem would fetch item from our Fake Db having our Fake Content tree. Now when you would navigate to db.GetItem's definition you would find no overload corresponding to GetItem(string path , Language language) overload in FakeDb beacuse of which the method always returns null. Fake Db source code does handle language calls but needs the second parameter language in string form which it parses as a language internally. I hope i was able to highlight my problems better in this case. Would really appreciate your help.

Regards, Nitin

NitinShuklaML avatar Jan 15 '20 08:01 NitinShuklaML

@NitinShuklaML, could you please post a minimal reproducible unit test which I can run and see which part fails?

sshushliapin avatar Jan 16 '20 13:01 sshushliapin

The issue subject is pretty clear:

FakeDb does not have GetItem(string path, Language lang) overload

I'd like to understand why would you need one and why the current implementation is not sufficient.

sshushliapin avatar Jan 17 '20 08:01 sshushliapin