Moq & Rhinomocks
Testing with mock objects typically has the following three key steps:
- Use interfaces to describe objects that need to be tested
- Implement this interface for the actual product code
- Implement this interface in a mock object for testing purposes
In the process of using mock objects, the design principle of "interface-oriented programming" is fully embodied, and the good design of the class is also promoted.
Self-fulfilling mock objects is quite tedious work, and fortunately, there are several excellent mock frameworks available in the. NET world that are currently the most commonly used MOQ and rhino mocks frameworks. The latest versions of the two are increasingly consistent in the use of the mocking API, relying on lambda expressions, generics, and extension methods to make great improvements, with the goal of allowing mock objects to integrate with multiple unit test frameworks in a more natural way, with a clear syntax to describe expectations, parameter constraints, The return value, etc., greatly facilitates the use of the developer.
Since both MOQ and Rhino mocks use castle Dynamicproxy to dynamically generate proxy classes, there are limitations on objects that require mock: The method being tested must be of type virtual.
Here is an example of the different implementations of the two (this example is from the samples in the MOQ source code package, just slightly modified to show the characteristics of both):
The object that needs to be tested is as follows:
Expand
The following is the unit test code implemented with these two mock frameworks:
| MOQ 4.0 |
Rhino Mocks 3.6 |
[test]public void Testpresenterselection () {//arrange var MView = n EW mock<iordersview> (); var mrepository = new mock<irepository<order>> (); var presenter = new Orderspresenter (Mview.object, mrepository.object); Check that the presenter have no selection by default Assert.null (presenter. Selectedorder); Raise Event mview.raise (io + = io. Orderselected + = null, new OrderEventArgs {order = New Order ("MOQ", 50)}); Assert Assert.notnull (presenter. Selectedorder); Assert.AreEqual ("MOQ", presenter. Selectedorder.productname);} |
[test]public void Testpresenterselection () {//arrange var MView = M Ockrepository.generatemock<iordersview> (); var mrepository = mockrepository.generatemock<irepository<order>> (); var presenter = new Orderspresenter (MView, mrepository); Check that the presenter have no selection by default Assert.null (presenter. Selectedorder); Raise Event mview.raise (io + = io. Orderselected + = null, NULL, new OrderEventArgs {order = New Order ("MOQ", 50)}); Assert Assert.notnull (presenter. Selectedorder); Assert.AreEqual ("MOQ", presenter. Selectedorder.productname);} |
[test]public void Testretrieveorders () {//arrange var MView = new M Ock<iordersview> (); var mrepository = new mock<irepository<order>> (); var presenter = new Orderspresenter (Mview.object, mrepository.object); list<order> defaultorders = new List<order> {New Order ("MOQ"), New Order ("Rhinomock")}; Mrepository.setup (r = R.findall ()). Returns (defaultorders); Exercise mocks presenter. OnInit (); Assert Mview.verifyset (v = v.orders = defaultorders);} |
[test]public void Testretrieveorders () { //arrange var mView = Mockrepository.generatemock<iordersview > (); var mrepository = mockrepository.generatestub<irepository<order>> (); var presenter = new Orderspresenter (MView, mrepository); list<order> defaultorders = new list<order> {New Order ("MOQ"), New Order ("Rhinomock")}; Mrepository.stub (ir + = ir. FindAll ()). Return (defaultorders); Exercise mocks presenter. OnInit (); Assert mview.assertwascalled (v = v.orders = defaultorders);} |
Conclusion
With the example above we can easily see that both syntax and API are very close to each other, using either of them can be easily implemented for your testing purposes.
References
- Quickstart-moq
- [email protected] -Rhino Mocks 3.5
- Daniel Cazzulino ' s blog-why do we need yet another NET mocking framework
Category: C # Tags: Moq, Rhino Mocks
Moq and Rhinomocks