0

Lets say i have the following controller:

    //
    // GET: /Courses/Edit/5
    public ActionResult Edit(int id)
    {
        Course course = courseService.GetCourseByID(id);
        if (course != null && course.userCanAccess())
        {
            // Do stuff...
        }
    }

The if statement is designed as a simple check to ensure the user can go ahead with the action. The Course entity itself provides the logic to determine if the user can access it. This works well but does lead me to a problem: how to test the controller.

I need a way to ensure that course.userCanAccess() returns a specific result in my controller test. My entity POCOs do not have interfaces so I don't believe I can mock them (please correct me if this is wrong).

My thinking is I could just create a full Couse object for the test which is configured so that userHasAccess() will return what I want but the method relies on certain related entities of Course being "hydrated" and so could become a chore to wire up.

I am new to testing so am unsure how to proceed.

James
  • 1,979
  • 5
  • 24
  • 52

2 Answers2

2

You can mock them if they have the methods you want to mock marked as virtual.

Ivo
  • 8,172
  • 5
  • 27
  • 42
0

POCOs should not contain any business logic. They are "Plain Old CLR Objects".

Your business logic should be in a Service Layer which you can inject into your controller.

If you need to add extra properties to your POCOs, that's okay (mark them as [NotMapped]), or you can (and should) use ViewModels, which is what Darin Dimitrov will probably tell you!

You are right in thinking that POCOs should not require interfaces. Indeed, uaing interfaces for POCOs makes using EntityFramework navigation properties almost impossible (but not actually impossible, I've done it, albeit in a very crappy, hacky way).

I can answer more fully later, but right now I need to get home to my wife and child!

Community
  • 1
  • 1
Tom Chantler
  • 14,753
  • 4
  • 48
  • 53
  • While I agree that Course is not a POCO, I have to disagree that business logic always must belong in a service layer. You can use a service pattern in the domain layer, or you can put methods directly on an entity. Adding a method to an entity enriches the domain model, even if it causes a Clr Object to be more than Plain Old. – danludwig Jan 10 '12 at 18:42
  • 1
    Fair point. I was just saying that, by definition, a POCO cannot contain business logic. You are allowed to put business logic anywhere you like, but once it goes into what was a POCO, it ceases to be a POCO. :-) – Tom Chantler Jan 10 '12 at 21:03
  • I think the term POCO means it's just a class not tied to any technology or framework other than the CLR. A domain layer class is often a POCO and a ViewModel is usually a POCO. ViewModels should not have any business logic (agreed), domain layer classes should have business logic if you are following DDD... – drogon Feb 06 '12 at 20:13
  • @Dommer - As has been stated in a number of other questions on SO, that just isn't true. POCO isn't synonymous with "Plain Old Data Object," as you're implying. See Martin Fowler's discussion on the [anemic domain model](http://martinfowler.com/bliki/AnemicDomainModel.html) for more on the matter. – Derek Mar 09 '12 at 21:21
  • @Derek: My understanding of the term `POCO` was that it was indeed synonymous with "Plain Old Data Object" as you've said and I believe it is nearly always is when used in the context of ASP.NET MVC. I've read a lot by Martin Fowler and I wasn't suggesting that placing business logic in the domain model was a bad idea, I was merely suggesting that to do so meant it should no longer be called a `POCO`. In this question of semantics apparently I was mistaken, but I know I am not unique in that respect. Thanks for the clarification. – Tom Chantler Mar 12 '12 at 11:49