<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 21:35:46 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CSHARP-89] Adding virtual to Insert, Update, and Save</title>
                <link>https://jira.mongodb.org/browse/CSHARP-89</link>
                <project id="10041" key="CSHARP">C# Driver</project>
                    <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Example usage in unit test (using RhinoMocks):&lt;/p&gt;

&lt;p&gt;public class DatabaseFactory&lt;br/&gt;
{&lt;br/&gt;
        public static MongoDatabase Create()&lt;/p&gt;
        {
            var server = MockRepository.GenerateStub&amp;lt;MongoServer&amp;gt;(new MongoConnectionSettings());
            var database = MockRepository.GenerateStub&amp;lt;MongoDatabase&amp;gt;(server, &quot;doesntmatter&quot;);

            var foos= MockRepository.GenerateStub&amp;lt;MongoCollection&amp;lt;BsonDocument&amp;gt;&amp;gt;(database, &quot;foos&quot;);
            database.Stub(x =&amp;gt; x.GetCollection(&quot;foos&quot;)).Return(foos);
            questions.Stub(x =&amp;gt; x.Insert&amp;lt;BsonDocument&amp;gt;(new BsonDocument()));

            // add other mocked document collections here
            
            return database;
        }
&lt;p&gt;    }&lt;/p&gt;

&lt;p&gt;This allows defensively checking boundary conditions in repositories, and if they all pass the database isn&apos;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;</description>
                <environment></environment>
        <key id="13569">CSHARP-89</key>
            <summary>Adding virtual to Insert, Update, and Save</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="9">Done</resolution>
                                        <assignee username="robert@mongodb.com">Robert Stam</assignee>
                                    <reporter username="robert.schooley">Robert Schooley</reporter>
                        <labels>
                    </labels>
                <created>Fri, 29 Oct 2010 21:57:11 +0000</created>
                <updated>Wed, 19 Oct 2016 22:38:41 +0000</updated>
                            <resolved>Wed, 19 Jan 2011 20:38:23 +0000</resolved>
                                                                    <component>Feature Request</component>
                                        <votes>0</votes>
                                    <watches>0</watches>
                                                                                                                <comments>
                            <comment id="22514" author="rstam" created="Wed, 19 Jan 2011 20:38:23 +0000"  >&lt;p&gt;Implemented. Made public properties and methods of MongoServer, MongoDatabase, MongoCollection and MongoCursor virtual to enable the use of mock object unit testing frameworks. &lt;/p&gt;</comment>
                            <comment id="20345" author="robert.schooley" created="Tue, 16 Nov 2010 03:39:45 +0000"  >&lt;p&gt;I marked the public methods and properties and everything passed my tests.  &lt;/p&gt;

&lt;p&gt;Findings:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The internal constructor on MongoCursor wouldn&apos;t work so I had to mark it public.
	&lt;ul&gt;
		&lt;li&gt;This isn&apos;t the case when using the interface approach as the concrete type is never called.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;The url passed into MongoUrl has to be valid as there is a concrete dependency on MongoUrlBuilder inside the constructor&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Attached is an example of how the classes are mocked/stubbed.  I have included the interface based approach as a reference point.&lt;/p&gt;</comment>
                            <comment id="20336" author="rstam" created="Mon, 15 Nov 2010 21:53:31 +0000"  >&lt;p&gt;Thanks. Let me know what you find out. I wasn&apos;t planning to work on this right away.&lt;/p&gt;</comment>
                            <comment id="20335" author="robert.schooley" created="Mon, 15 Nov 2010 21:44:17 +0000"  >&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;cursor.Stub(x =&amp;gt; x.GetEnumerator())&lt;br/&gt;
    .Return(null)&lt;br/&gt;
    .WhenCalled(x =&amp;gt; x.ReturnValue = new List&amp;lt;BsonDocument&amp;gt;().GetEnumerator());&lt;/p&gt;

&lt;p&gt;The only thing I can think of is possibly MapReduce at some point.&lt;/p&gt;

&lt;p&gt;Before you go through this effort I&apos;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&apos;s internal constructor and I don&apos;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.&lt;/p&gt;</comment>
                            <comment id="20333" author="rstam" created="Mon, 15 Nov 2010 21:11:57 +0000"  >&lt;p&gt;I don&apos;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&apos;t otherwise need to be virtual doesn&apos;t really change or complicate the API but gives the mock object frameworks what they need.&lt;/p&gt;

&lt;p&gt;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 &lt;b&gt;might&lt;/b&gt; make sense is MongoCursor, but deeper than that and I think you are creating mock objects at way too low a level.&lt;/p&gt;</comment>
                            <comment id="19847" author="robert.schooley" created="Fri, 29 Oct 2010 22:02:55 +0000"  >&lt;p&gt;I&apos;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.&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                            <attachment id="10598" name="WithInterfaces.txt" size="817" author="robert.schooley" created="Tue, 16 Nov 2010 03:39:45 +0000"/>
                            <attachment id="10597" name="WithVirtual.txt" size="1351" author="robert.schooley" created="Tue, 16 Nov 2010 03:39:45 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hrh9r3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>14379</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>