[CSHARP-89] Adding virtual to Insert, Update, and Save Created: 29/Oct/10 Updated: 19/Oct/16 Resolved: 19/Jan/11 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Feature Request |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Robert Schooley | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Description |
|
Adding virtual to the overloads of Insert, Update, and Save in MongoCollection will make unit testing much easier. I pulled the source and made the change for Insert and it does work as expected. Example usage in unit test (using RhinoMocks): public class DatabaseFactory } This allows defensively checking boundary conditions in repositories, and if they all pass the database isn't actually called. The server process can actually be turned off and all unit tests can be run, and then turned on for integration tests. Maybe a mocking super genius has a better way, but this is the best I could come up with after a while of fiddling around. |
| Comments |
| Comment by Robert Stam [ 19/Jan/11 ] |
|
Implemented. Made public properties and methods of MongoServer, MongoDatabase, MongoCollection and MongoCursor virtual to enable the use of mock object unit testing frameworks. |
| Comment by Robert Schooley [ 16/Nov/10 ] |
|
I marked the public methods and properties and everything passed my tests. Findings:
Attached is an example of how the classes are mocked/stubbed. I have included the interface based approach as a reference point. |
| Comment by Robert Stam [ 15/Nov/10 ] |
|
Thanks. Let me know what you find out. I wasn't planning to work on this right away. |
| Comment by Robert Schooley [ 15/Nov/10 ] |
|
Those three classes sound good to me. Additionally, I did hit down to MongoCursor GetEnumerator when calling a foreach loop in a repository method, so that class probably needs it too: cursor.Stub(x => x.GetEnumerator()) The only thing I can think of is possibly MapReduce at some point. Before you go through this effort I'd like to pull out the interfaces and mark the methods as virtual ion my local copy to make sure it all works correctly. I had some issues around MongoCursor's internal constructor and I don't know if virtual will help there. I have unit tests with the interface approach so I can do a fresh pull of the driver and recompile it with virtual and know pretty quickly if there are any issues. |
| Comment by Robert Stam [ 15/Nov/10 ] |
|
I don't want to create interfaces for every class (or top level class). But it does seem like a good compromise to make all the public properties and methods of MongoServer, MongoDatabase and MongoCollection virtual. That should be enough to allow mock object frameworks like RhinoMocks to mock these classes. By compromise I mean: making the properties and methods virtual even though they wouldn't otherwise need to be virtual doesn't really change or complicate the API but gives the mock object frameworks what they need. So where do we stop? Is it enough to put virtual on the three classes just mentioned? How far down do you want to go when creating mock objects for the C# driver classes? One other class that might make sense is MongoCursor, but deeper than that and I think you are creating mock objects at way too low a level. |
| Comment by Robert Schooley [ 29/Oct/10 ] |
|
I'd also like to add another way to do this may be to extract an interface from MongoDabase. I did that and all was fine and dandy until I had to update dependencies in the driver to use the interface and sparks started to fly. I promptly stopped. |