asp.net mvc - How to use Moq with Entity Framework IDbSet Count() etc. methods -
i'm trying use moq
make tests entity framework code first classes. i'm new moq , mocking techniques , wonder if it's possible test describe below. searched through web solutions, based on repository pattern, want avoid.
i have itestentities
interface context
public interface itestentities { idbset<order> orders { get; } idbset<product> products { get; } idbset<user> users { get; } }
then context
public class testentities : dbcontext, itestentities { public testentities() : base("name=testentities") { } public virtual idbset<order> orders { get; set; } public virtual idbset<product> products { get; set; } public virtual idbset<user> users { get; set; } }
a controller , action test
public class homecontroller : controller { private itestentities db; public homecontroller() { db = new testentities(); } public homecontroller(itestentities db) { this.db = db; } public actionresult index() { var count = db.users.count(); viewbag.count = count; return view(count); } }
and nunit test using moq
[test] public void modelvalueshouldbetwo() { var mockusers = new mock<idbset<user>>(); mockusers.setup(m => m.count()).returns(2); var mockdb = new mock<itestentities>(); mockdb.setup(db => db.users).returns((idbset<user>)mockusers); var controller = new homecontroller((itestentities)mockdb); var view = controller.index(); assert.isinstanceof<viewresult>(view); assert.areequal(((viewresult)view).model, 2); }
the problem line: mockusers.setup(m => m.count()).returns(2);
. when running test following error:
system.notsupportedexception : expression references method not belong mocked object: m => m.count<user>()
i think due .count()
being static method cannot mocked moq. there way test simple action using moq , not using full-fledged repository pattern, understand should anyway have .count()
part hardcoded method testable... maybe use mocks in wrong way? because have impression should quite simple , possible ef code first.
if mocking test entities don't need mock further down chain
something should (although, 'm not @ ide may need tweaking)
update include new inmemorydbset
[test] public void modelvalueshouldbetwo() { //build test users var mockusers = new inmemorydbset<user>(){ new user(), new user()}; var mockdb = new mock<itestentities>(); //set mock entities returntest users. mockdb.setup(db => db.users).returns(mockusers); var controller = new homecontroller((itestentities)mockdb); var view = controller.index(); assert.isinstanceof<viewresult>(view); assert.areequal(((viewresult)view).model, 2); }
this mean extension methods work off of test data have supplied.
see below article on mocking dbset http://geekswithblogs.net/aligned/archive/2012/12/12/mocking-or-faking-dbset.aspx