Keyboard Shortcuts
Likes
- Testdrivendevelopment
- Messages
Search
Testing a class which utilizes randomness
Nikola Novak
Hello! I'm new to TDD and this group. For practice, I started a simple project and now I want to create a list of random strings, but such that no two strings are ever the same. In a very unlikely, yet possible case, when two randomly generated strings are the same, the method that does this should discard the duplicate and generate a new string before it returns.
What I want to test is exactly this behavior - the code which discards the duplicate and forces the string to be regenerated. To test that, I need to force the random string generator to return a duplicate at least once (but finite number of times). To create the test which would generate strings until there's at least one duplicate is unrealistic, because such a test could take a very long time to complete.
How would I write such a test? Kind regards, Nikola |
Re: How do I unit test a Dispose method ?
Whoops just saw yesterday's message came in all garbled.. here it is again properly formatted.. ========================== Hi again Gishu and all,? Seems like this thread has grown since I last looked :) What I used to do in this case is inject the disposable object as a collaborator (interface representing its role) into the class that uses it,? so the class that uses it doesn't need to know about if it is or isn't disposable. E.g:? class connection? { ?ISecurePassword pswd? } interface ISecurePassword? {? ?Void doSomethingThatSecurePasswordsDo();? } class DispisableSecurePassword : ISecurePassword, IDisposable { ? ...? } Application: void Main(){ ? using (DisposableSecurePassword pswd = new DisposableSecurePassword()) ? { ? ? Connection conn = new connection(pswd): ? ? conn.DoSomethingThatNeedsToBeDone(); ? } } Makes any sense?? Written hastily from iPhone waiting for a buss Avi |
Re: How do I unit test a Dispose method ?
Hi again Gishu and all,
Seems like this thread has grown since I last looked :)
What I used to do in this case is inject the disposable object as a collaborator (interface representing its role) into the class that uses it, so the class that uses it doesn't need to know about if it is or isn't disposable.
E.g:
Class connection {
ISecurePassword pswd
}
Interface ISecurePassword {
Void doSomethingThatSecurePasswordsDo();
}
Class dispisableSecurePassword : ISecurePassword, IDisposable{
...
}
Application:
Using (disposableSecurePassword pswd = new disposableSecurePassword()){
Connection conn = new connection(pswd):
...
}
Makes any sense?
Written hastily from iPhone waiting for a buss
Avi
|
Re: How do I unit test a Dispose method ?
Nope. I did test-drive this design. The connection instance represents an open connection to a hardware device. All conn parameters appear as constructor parameters of this type - one of which is a SecureString password.Connection(conn params) The type creates a copy of the same in the ctor and holds on to it for subsequent API calls to the device Finally it has a Disconnect method that closes the connection. { } However there isn't any clean way to know this - unless IDisposable interface had a bool IsDisposed property. A crude way would be to invoke another member and expect an ObjectDisposedException (if the type has been well written) |
Re: [TDD] RE: How do I unit test a Dispose method ?
Donaldson, John
¿ªÔÆÌåÓýYes, +1 to that. ? I¡¯ve been wondering what the business or functional need was that was driving that particular implementation and whether it might have been done differently. And for sure it would work out differently if you used a language that didn¡¯t ¡°dispose¡±. ? John D. ? From: testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of avi_a@...
Sent: 05 February 2014 08:58 To: testdrivendevelopment@... Subject: [TDD] RE: How do I unit test a Dispose method ? ?
Hi Gishu ? Sorry if my reply is out of context - I've been having trouble finding all the replies in the new (?) Yahoo group UI.... ? In general - the idea is the tests drive your design. Here it sounds like you have a predefined design (a Connection wrapping your disposable SecireString member) and now you want to test iot (after the code is written). Did I understand that correctly? ? Either way - TDDing this would probably produce a whole different design, depending on your requirements... I'd love to give it a go - could you give some more context? as to how you ended up with this design and what the requirements are? ? Best, Avi ?
|
Re: How do I unit test a Dispose method ?
Hi Gishu Sorry if my reply is out of context - I've been having trouble finding all the replies in the new (?) Yahoo group UI.... In general - the idea is the tests drive your design. Here it sounds like you have a predefined design (a Connection wrapping your disposable SecireString member) and now you want to test iot (after the code is written). Did I understand that correctly? Either way - TDDing this would probably produce a whole different design, depending on your requirements... I'd love to give it a go - could you give some more context? as to how you ended up with this design and what the requirements are? Best, Avi |
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓýAHA! But then a factory should not be using the objects it creates¡. J ? From: testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of Avi Kessner
Sent: Monday, February 03, 2014 8:40 AM To: testdrivendevelopment@... Subject: RE: [TDD] How do I unit test a Dispose method ? ? ? Unless it's a factory On Feb 3, 2014 6:34 PM, "Amir Kolsky" <amir.kolsky@...> wrote: ? I agree, my point is that you should ALWAYS be given the object rather than it belonging to you. Therefore, the whole IDisposable pattern seems flawed from a design perspective. ? All that said, you can still test drive a flawed design¡. J ? From:
testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of Brad Wilson ? ? ...except, if you're given the object rather than creating it yourself, then its lifetime doesn't belong to you, and you don't need to be concerned with whether it's disposable. ? On Sun, Feb 2, 2014 at 11:36 PM, Amir Kolsky <amir.kolsky@...> wrote: ? If A cares about this specific property it would require B to implement IDisposable. From A¡¯s perspective, it is given an object of type B to perform a specific action. B would be available to A through an interface, not an implementation. Hence A would not know that (say) B1 is the implementation of B, but rather know about B alone ? ? From:
testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin ? ? Amir, I feel like I might be missing your point.? ? Why is it unreasonable for A to know that B uses expensive resources and provides a way to release them early? Surely this was one of the considerations when choosing B over X or Y or Z. IMHO it's a characteristic, not an implementation detail. ? On 3 February 2014 15:19, Amir Kolsky <amir.kolsky@...> wrote: ? ? Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. ? n? This is inane, as it requires the owning object to know about implementation details of it¡¯s ownee. I disagree. All that A needs to know is that B implements the IDisposable interface. ? ? * A has to know about something pertaining to B that has nothing to do with why A needs it. ? ? ?
|
Re: [TDD] How do I unit test a Dispose method ?
Unless it's a factory On Feb 3, 2014 6:34 PM, "Amir Kolsky" <amir.kolsky@...> wrote:
|
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓýI agree, my point is that you should ALWAYS be given the object rather than it belonging to you. Therefore, the whole IDisposable pattern seems flawed from a design perspective. ? All that said, you can still test drive a flawed design¡. J ? From: testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of Brad Wilson
Sent: Monday, February 3, 2014 7:48 AM To: testdrivendevelopment@... Subject: Re: [TDD] How do I unit test a Dispose method ? ? ? ...except, if you're given the object rather than creating it yourself, then its lifetime doesn't belong to you, and you don't need to be concerned with whether it's disposable. ? On Sun, Feb 2, 2014 at 11:36 PM, Amir Kolsky <amir.kolsky@...> wrote: ? If A cares about this specific property it would require B to implement IDisposable. From A¡¯s perspective, it is given an object of type B to perform a specific action. B would be available to A through an interface, not an implementation. Hence A would not know that (say) B1 is the implementation of B, but rather know about B alone ? ? From:
testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin ? ? Amir, I feel like I might be missing your point.? ? Why is it unreasonable for A to know that B uses expensive resources and provides a way to release them early? Surely this was one of the considerations when choosing B over X or Y or Z. IMHO it's a characteristic, not an implementation detail. ? On 3 February 2014 15:19, Amir Kolsky <amir.kolsky@...> wrote: ? ? Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. ? n? This is inane, as it requires the owning object to know about implementation details of it¡¯s ownee. I disagree. All that A needs to know is that B implements the IDisposable interface. ? ? * A has to know about something pertaining to B that has nothing to do with why A needs it. ? ? ?
|
Re: [TDD] How do I unit test a Dispose method ?
Brad Wilson
...except, if you're given the object rather than creating it yourself, then its lifetime doesn't belong to you, and you don't need to be concerned with whether it's disposable. On Sun, Feb 2, 2014 at 11:36 PM, Amir Kolsky <amir.kolsky@...> wrote:
|
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓýIf A cares about this specific property it would require B to implement IDisposable. From A¡¯s perspective, it is given an object of type B to perform a specific action. B would be available to A through an interface, not an implementation. Hence A would not know that (say) B1 is the implementation of B, but rather know about B alone ? ? From: testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin
Sent: Sunday, February 2, 2014 9:40 PM To: testdrivendevelopment@... Subject: Re: [TDD] How do I unit test a Dispose method ? ? ? Amir, I feel like I might be missing your point.? ? Why is it unreasonable for A to know that B uses expensive resources and provides a way to release them early? Surely this was one of the considerations when choosing B over X or Y or Z. IMHO it's a characteristic, not an implementation detail. ? On 3 February 2014 15:19, Amir Kolsky <amir.kolsky@...> wrote: ? ? Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. ? n? This is inane, as it requires the owning object to know about implementation details of it¡¯s ownee. I disagree. All that A needs to know is that B implements the IDisposable interface. ? ? * A has to know about something pertaining to B that has nothing to do with why A needs it. ?
|
Re: [TDD] How do I unit test a Dispose method ?
Amir, I feel like I might be missing your point.? Why is it unreasonable for A to know that B uses expensive resources and provides a way to release them early? Surely this was one of the considerations when choosing B over X or Y or Z. IMHO it's a characteristic, not an implementation detail.
On 3 February 2014 15:19, Amir Kolsky <amir.kolsky@...> wrote:
|
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓý? Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. ? n? This is inane, as it requires the owning object to know about implementation details of it¡¯s ownee. I disagree. All that A needs to know is that B implements the IDisposable interface. ? ? * A has to know about something pertaining to B that has nothing to do with why A needs it. |
Re: [TDD] How do I unit test a Dispose method ?
On 3 February 2014 14:48, Amir Kolsky <amir.kolsky@...> wrote:
I disagree. All that A needs to know is that B implements the IDisposable interface.
?
The only reason to ever call Dispose() is to initiate an early release of expensive internal resources. If the original creator of B is finished with B, then it should call B.Dispose(). If it isn't then it shouldn't. If unsure, don't call Dispose(),and?the garbage collector will eventually clean up your IDisposables anyway.
Given that this only applies to expensive resources, then ideally the tying up, use and release of those resources should be as close to each other as possible. Say B has an Open() and Close() method, and Close() calls Dispose() internally, B can still be injected and still implement IDisposable. It's construction and use can still be separated.
|
Re: [TDD] How do I unit test a Dispose method ?
On 3 February 2014 14:39, Amir Kolsky <amir.kolsky@...> wrote:
I agree that it is difficult. Here is the test list that I used:
To conform to the, the target class must also:
Some of these were challenging (or impossible) to write automated tests for, some were just messy. |
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓý? Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable. ? n? This is inane, as it requires the owning object to know about implementation details of it¡¯s ownee. ? I agree completely. My original point was about not injecting B and then disposing of it. ??????????????? So how would the original creator of B know when to dispose of it? And given that separation of use from construction is dogmatic, you will always encounter this problem¡. ?
?
|
Re: [TDD] How do I unit test a Dispose method ?
On 3 February 2014 14:37, Amir Kolsky <amir.kolsky@...> wrote:
Except that B must already be IDisposable. The IDisposable pattern requires that any object that owns an IDisposable must itself implement IDisposable.
?
I agree completely. My original point was about not injecting B and then disposing of it.
?
|
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓýThis only applies to objects that it owns. Otherwise if it dispose of a reference that has been passed to it (say through injection) then it may be closing an object that is still required elsewhere. ? Which is the problem with IDisposable to begin with. It is well-nigh impossible to define the behavior properly. ? ? On 3 February 2014 14:33, David Burstin <david.burstin@...> wrote:
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 <amir.kolsky@...> wrote: ? Should an IDisposable object call Dispose on the IDisposable objects that it holds? ? From:
testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin
? ? Hi all. Long time listener, first time caller :) ? I've just finished a blog post called? ? 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 <john.m.donaldson@...> wrote: ? .a. Yes, you are right it's an implementation detail.
------------------------------------ ? ? ?
|
Re: [TDD] How do I unit test a Dispose method ?
¿ªÔÆÌåÓý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? ? 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.¡± ? A. ? From: testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin
Sent: Sunday, February 2, 2014 7:33 PM To: testdrivendevelopment@... 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 <amir.kolsky@...> wrote: ? Should an IDisposable object call Dispose on the IDisposable objects that it holds? ? From:
testdrivendevelopment@... [mailto:testdrivendevelopment@...]
On Behalf Of David Burstin
? ? Hi all. Long time listener, first time caller :) ? I've just finished a blog post called? ? 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 <john.m.donaldson@...> wrote: ? .a. Yes, you are right it's an implementation detail.
------------------------------------ ? ?
|
Re: [TDD] How do I unit test a Dispose method ?
Sorry - hit send too early: 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.
This only applies to objects that it owns. Otherwise if it dispose of a reference that has been passed to it (say through injection) then it may be closing an object that is still required elsewhere.
On 3 February 2014 14:33, David Burstin <david.burstin@...> wrote:
|