Moq: Mocking Method by using Moq Mocking Framework

4/1/2014

This's about how to mock method using Moq Mocking Framework. So, basically, Interface is good way to go, eventhough your method is get only, it's able to mock your method to result different data. There's one thing you need to remembers, Mocking can only mock Interface, abstarct, virtal, but sealed class. for example if you have following kind of class and interface.

Interface
 	public  interface  IClass 
 	{
 		int  Total();
 		string  GetOnlyMethod();
 
 
Class
 	class  Class  : IClass 
 	{
 		public  int  Total()
 		{
 			return  Number * Price;
 		}
 
 		public  string  GetOnlyMethod()
 		{
 			return  "get only method" ;
 		}
 
Sample code of mocking Interface vs Class ==> method mocking
 Mock <Class > mockClass = new  Mock <Class >();
 			mockInterface.Setup(x => x.Total()).Returns(9);
 			var  totalClass = mockInterface.Object.Total();
 
 			Mock <Class > mockReadOnlyMethod = new  Mock <Class >();
 			mockReadOnlyMethod.Setup(x => x.GetOnlyMethod()).Returns("can i change?" );
 			var  totalReadOnlyMethod = mockReadOnlyMethod.Object.GetOnlyMethod();
 

So, First Total() will run thouht, but you'll get run-time error when you mock GetOnlyMethod(), like following image.

You can't mock class not Get only property on your class

 

However, if you mock the Interface like following it's gonna work.

Mock Get only method
 			Mock <IClass > mockReadOnlyMethod2 = new  Mock <IClass >();
 			mockReadOnlyMethod2.Setup(x => x.GetOnlyMethod()).Returns("can i change? yes!" );
 			var  totalReadOnlyMethod2 = mockReadOnlyMethod2.Object.GetOnlyMethod();
 

Also, if you class is Public, and Method is Virtual works fine too.

Virtual Method
 	public  virtual  string  MyVirtualMethod()
 		{
 			return  "hello virtul" ;
 		}
 

In addition, your class, method is abstarct, you could mock you method's value too.

Abstract Method
 	public  abstract  class  Class  : IClass 
 	{
 		public  abstract  string  MyAbstractMethod();
 

You could also write like following depend on what's you set, return different result.

Condition showing different resutl value
 		Mock <IClass > testGetSet = new  Mock <IClass >();
 			testGetSet.Setup(x => x.GetOnlyMethod2("no" )).Returns("yyy" );
 			testGetSet.Setup(x => x.GetOnlyMethod2("yes" )).Returns("yesyes" );
 			var  testGetSet2 = testGetSet.Object.GetOnlyMethod2("no" );
 			var  testGetSet4 = testGetSet.Object.GetOnlyMethod2("yes" );
 

Or, like following user can put any string, and return specific result

parameter string only
 	Mock <IClass > testGetSet3 = new  Mock <IClass >();
 			testGetSet3.Setup(x => x.GetOnlyMethod2(It .IsAny<string >()));
 			var  testGetSet4t = testGetSet3.Object.GetOnlyMethod2("nonono" );
 

Basically, best practice is mock your interface class.