Re: How do I unit test a Dispose method ?
David Burstin <[email protected]> Mon, 3 Feb 2014 14:44:00 +1100
| Newsgroups | gmane.comp.programming.test-driven-development |
|---|---|
| Message-ID | <CAKKh91CxcGM63aTk1u5gUMmDj8qhXM9HzF3XoJ+Ggu6rT_H-Mw@mail.gmail.com> |
On 3 February 2014 14:37, Amir Kolsky <[email protected]> wrote: > > > That is what I thought. So I object A uses B and C and C (and A) are > IDisposable, we need to ascertain that C's Dispose is called, right? > > > > Note, however, that the fact that A uses B and C, is an implementation > detail and as such in our test we probably do not want to deal with C > explicitly. What happens, for example, if B suddenly becomes IDisposable? > Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. > > > This is why I said that the approach should be generic, so that A will say > "since I am IDisposable, I will make sure that any of my members which are > also IDiposable will be Disposed of." In place of saying "I will Dispose of > C." > I agree completely. My original point was about not injecting B and then disposing of it. > > > A. > > > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *David Burstin > *Sent:* Sunday, February 2, 2014 7:33 PM > > *To:* [email protected] > *Subject:* Re: [TDD] How do I unit test a Dispose method ? > > > > > > It depends. > > > > If its Dispose() method has been called (its owner has requested early > release of its resources), then it is required to call Dispose() on all of > its IDisposable objects. > > > > However, if its Dispose() method is not called then cleanup is ultimately > initiated by the GC through the Finalization Queue. As the order of > finalization is not guaranteed, the object must not call Dispose() on any > of its IDisposable objects. > > > > On 3 February 2014 14:28, Amir Kolsky <[email protected]> > wrote: > > > > Should an IDisposable object call Dispose on the IDisposable objects that > it holds? > > > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *David Burstin > *Sent:* Sunday, February 2, 2014 7:25 PM > *To:* [email protected] > > > *Subject:* Re: [TDD] How do I unit test a Dispose method ? > > > > > > Hi all. Long time listener, first time caller :) > > > > I've just finished a blog post called Growing IDisposable Guided By Tests<http://www.ambersolutions.com.au/dburstin/index.php/2014/02/03/growing-idisposable-guided-by-tests/> > > > > As IDisposable is primarily about managing internal resources, I agree > with Amir that the best approach is to subclass, which allows us to spy on > those resources. But I would not inject the resources to spy on as only the > owner of the resource is responsible for its disposal - in this case the > owner would be the test, not the SUT. > > > > > > > > On 24 January 2014 19:28, Donaldson, John <[email protected]> wrote: > > > > .a. Yes, you are right it's an implementation detail. > Would another way make things easier? > > For example, separate the storing of the password from the Connection. > You might delegate to the PasswordStore to hold and remove passwords. > Then you just need to show that: > - the PasswordStore is wired up to the Connection > - the PasswordStore does what you want. > > John D. > > > > -----Original Message----- > From: [email protected] [mailto: > [email protected]] On Behalf Of Amir Kolsky > Sent: 24 January 2014 03:07 > To: [email protected] > Subject: RE: [TDD] How do I unit test a Dispose method ? > > Here's another way of thinking about this - Whether a member is > IDisposable or not is really an implementation issue (as which members > comprise an object is private). > So the general question here is how do we get an object to identify all of > its IDisposable private methods and invoke Dispose on them in its Dispose. > There are several ways I can think of doing this, all of which are sort of > terrible, but then, we're dealing with a true implementation specific > problem. > > The underlying technique in all cases is going to be the injection of two > more members which are IDisposable mocks. > > We can try to .emit code at runtime that will add these mocks to the UUT, > but - ugh! > Partial classes could work, but then we'd have to mark the original as > partial, so - ugh! > The easiest is to subclass the original class and have the (mock) subclass > have two (mock) members whose Dispose() must be called. The implementation > would, naturally, have to use reflection to find all members and Dispose() > of them properly, but that's what we want to see anyway. > > The price to pay is that the class cannot be sealed, but that is really > not a problem as only API classes should be sealed anyway and if you class > serves both as an API and it actually does anything, shame on you :) > > .a. > > From: [email protected]<mailto: > [email protected]> [mailto: > [email protected]] On Behalf Of Roy Osherove > Sent: Thursday, January 23, 2014 4:18 AM > To: testdrivendevelopment > Subject: Re: [TDD] How do I unit test a Dispose method ? > > Isn't there already an IDisposable interface? which means you can easily > create an IDisposable MOCK object and check if dispose was called on it. > all you would do it then have casted IDisposable in the class level that > you would access from the dispose method. > > public Connection(SecureString password) { IDisposable > _myDisposablePassword; > _myPassword = password.Copy(); // creates a clone of the password which > needs to be disposed _myDisposablePassword = _myPassword; } public void > Dispose() { > _myDisposablePassword.Dispose(); // releases any resources it holds } On > Thu, Jan 23, 2014 at 12:06 PM, Gishu Pillai <[email protected] > <mailto:[email protected]>> wrote: > > public Connection(SecureString password) { > _myPassword = password.Copy(); // creates a clone of the password which > needs to be disposed } public void Dispose() { > _myPassword.Dispose(); // releases any resources it holds } > > SecureString is a .Net framework type. I could wrap it in an adapter to > ease testing...but doesn't solve the general problem. Wrapping all member > disposable type with interfaces is going to be tedious. > It seems this is a better fit for Static code analysis. > Gishu > > -- > Thanks, > > Roy Osherove > > - @RoyOsherove<https://twitter.com/RoyOsherove> > - Read my new book Notes to a Software Team Leader< > http://TeamLeadSkills.com> > - My blog for team leaders: http://5Whys.com > - +47-96-90-22-15<tel:%2B47-96-90-22-15 <%2B47-96-90-22-15>> (Oslo Time) > > [Non-text portions of this message have been removed] > > ------------------------------------ > > Yahoo Groups Links > > > > > > >