1

I am trying to learn TDD/BDD using NUnit and Moq.

The design that I have been following passes a DataService class to my controller to provide access to repositories.

I would like to Mock the DataService class to allow testing of the controllers.

There are lots of examples of mocking a repository passed to the controller but I can't work out how to mock a DataService class in this

scenerio.

Could someone please explain how to implement this?

Here's a sample of the relevant code:

[Test]
public void Can_View_A_Single_Page_Of_Lists()
{
    var dataService = new Mock<DataService>();

    var controller = new ListsController(dataService); 

    ...
}



namespace Services
{
    public class DataService
    {
        private readonly IKeyedRepository<int, FavList> FavListRepository;
        private readonly IUnitOfWork unitOfWork;

        public FavListService FavLists { get; private set; }

        public DataService(IKeyedRepository<int, FavList> FavListRepository,
        IUnitOfWork unitOfWork)
        {
            this.FavListRepository = FavListRepository;
            this.unitOfWork = unitOfWork;

            FavLists = new FavListService(FavListRepository);
    }

        public void Commit()
        {
            unitOfWork.Commit();
        }

    }
}



namespace MyListsWebsite.Controllers
{
    public class ListsController : Controller
    {
        private readonly DataService dataService;

        public ListsController(DataService dataService)
        {
            this.dataService = dataService;
        }


        public ActionResult Index()
        {
            var myLists = dataService.FavLists.All().ToList();

            return View(myLists);
        }

    }
}

1 Answer 1

2

Create an interface like this:

public interface DataService
{
    FavListService FavLists { get; }
    void Commit();
}

Make your DataService implement this interface and your controller should depend on this interface. Problem solved :)

EDIT: This line of code:

dataService.FavLists.All().ToList();

is breaking the law of demeter and will be a pain to unit test your service. Create a method like AllFavList() on your service instead of all these chain of calls, it will be easier to mock.

EDIT2: How to mock you get property

dataService.SetupGet(d => d.FavLists).Returns(your_variable);
Sign up to request clarification or add additional context in comments.

5 Comments

@Oenning - thanks. I have extracted the interface (the dataservice now implements this) and have changed the controller code to private readonly IDataService dataService; public ListsController(IDataService dataService){ this.dataService = dataService; } and the test is now var dataService = new Mock<IDataService>(); var controller = new ListsController(dataService); - I am getting an invalid arguments error. Is there more that I need to take me over the line?
try this new ListsController(dataService.Object);
@Oenning - trying this out now
@Oenning - yes that works to a point but how do I populate the FavList with some test data if the FavLists is only get?
@Oenning - unfortunately SetupGet is missing in the intellisense when I type dataService. or dataService.object - am I missing something further?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.