Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have the below code:

public interface IRepositoryService
{
    /// <summary>
    /// This will add conditions like Published = true, Deleted = false and PublisehdDate smaller than NOW
    /// 
    /// </summary>
    IRavenQueryable<T> AddConditionsToQueryToLoadOnlyAvailableForFrontend<T>(IRavenQueryable<T> query) where T : BaseObject;


}

public class HomepageBannerRepository : BaseRepository<HomepageBanner>, IHomepageBannerRepository
{
    public HomepageBannerRepository(IRepositoryService repositoryService)
        : base(repositoryService)
    {

    }

    public List<HomepageBanner> GetHomepageBanners()
    {
        var q = CreateQuery(loadOnlyItemsAvailableToFrontend: true, autoSortByPriority: true);
        var list = q.ToList();
        return list;
    }
}

The method IRepositoryService.AddConditionsToQueryToLoadOnlyAvailableForFrontend() adds general conditions to any query like Published=True and Deleted=False, as all my objects inherit from BaseObject which contains fields like Published, Deleted etc.

This has been tested, and for the method HomepageBannerRepository.GetHomepageBanners(), I would only like to verify that it was called (using mocks), rather than having to check via unit-testing that only published items are returned.

The current unit test I created is as below (using the SpecsFor framework)

        [TestFixture]
        public class GetHomepageBannerSpecs
        {
            [TestFixture]
            public class when_method_is_called : SpecsForRepository<HomepageBannerRepository>
            {
                private HomepageBanner _bannerA;
                private HomepageBanner _bannerB;
                private HomepageBanner _bannerC;
                private List<HomepageBanner> _results;

                private HomepageBanner createHomepageBanner()
                {
                    HomepageBanner banner = new HomepageBanner();
                    banner.Store();

                    return banner;
                }

                protected override void Given()
                {
                    _bannerA = createHomepageBanner();
                    _bannerB = createHomepageBanner();
                    _bannerC = createHomepageBanner();

                    GetMockFor<IRepositoryService>();
                    base.Given();
                }

                protected override void When()
                {
                    _results = SUT.GetHomepageBanners();
                    base.When();
                }

                [Test]
                public void then_it_should_return_all_homepage_banners()
                {
                    GetMockFor<IRepositoryService>().Verify(x => x.AddConditionsToQueryToLoadOnlyAvailableForFrontend(It.IsAny<IRavenQueryable<HomepageBanner>>()), Times.Once());
                    GetMockFor<IRepositoryService>().Verify(x => x.AddSortByPriorityToQuery(It.IsAny<IRavenQueryable<HomepageBanner>>()), Times.Once());

                    _results.ShouldContain(_bannerA);
                    _results.ShouldContain(_bannerB);
                    _results.ShouldContain(_bannerC);

                }
            }
        }

The main problem stems from that the actual implementation of HomepageBannerRepository.GetHomepageBanners() requires that the implemenation of the IRepositoryService returns a query, when IRepositoryService.AddConditionsToQueryToLoadOnlyAvailableForFrontend is called. Since I am using a mock, this returns NULL, and then it throws an ObjectNullReference exception.

First of all, is it possible to setup the Mock to return the same parameter passed as input parameter? Something like:

GetMockFor(IRepositoryService).Setup(x=>x.AddConditionsToQueryToLoadOnlyAvailableForFrontend(query)).Returns(query); 

I am using Moq as my mocking framework.

Also, I would like to receive any criticism regarding code, and where it could be structured better with regards to unit-testing / Test-Driven Development, dependency injection and any other comments are greatly welcome.

share|improve this question

1 Answer 1

Nice thing in participating/answering in forums like this is that you learn while you answer questions. I haven't heard about SpecsFor framework. Looks a bit tricky, but will definitely have a look later. Ok, back to your question :)

About your first question, setting up the mock - you can definitely do that, there are a number of overloaded Returns methods accepting delegate/lambda, depending on the number of parameters in the method being setup (here I setup the method to always return the same query regardless of the query passed:

GetMockFor(IRepositoryService)
    .Setup(x => x.AddConditionsToQueryToLoadOnlyAvailableForFrontend(It.IsAny<IRavenQueryable<HomepageBanner>>()))
    .Returns(q => q);

The code overally looks good except that Ayende suggests (and I completely agree with him) not to wrap RavenDB sessions into repositories. I would just create an extension method to add these filters to IRavenQueryable<T> where T:BaseObject

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.