Public vs Private members for factories implementing an interface [closed]
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Summary
Is there harm in exposing concrete class data as get-only public properties solely for the purposes of writing better unit tests?
Background
In general, I prefer to keep as much, if not all, of my data as private readonly
. This ensures consumers aren't bound to the data held but rather to the behaviors a type provides. One (potential) issue I've noticed recently is writing good unit tests for factory types that implement an interface. Consider the following illustrative example:
public interface IComponent
{
void DoStuff();
}
public interface IComponentDependency
{
void HelpInDoingStuff(int data);
}
public interface IFactory
{
IComponent CreateComponent(IComponentDependency dependency)
}
public class SpecialComponent : IComponent
{
private readonly int someOtherDependency;
private readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class SpecialComponentFactory : IFactory
{
private readonly int someOtherDependency;
public SpecialComponentFactory(int someOtherDependency)
{
this.someOtherDependency = someOtherDependency;
}
public IComponent CreateComponent(IComponentDependency dependency)
{
return new SpecialComponent(dependency, this.someOtherDependency);
}
}
When writing tests for SpecialComponentFactory
the only thing available publicly to test is that SpecialComponentFactory
returns an instance of SpecialComponent
. What if I'd also like to confirm that SpecialComponent
was indeed constructed with someOtherDependency
, or in fact, that he was constructed with the specified dependency
. To do this without reflection hacks we could make them protected
and subclass SpecialComponent
and then expose it publicly via a test fake:
public class SpecialComponent
{
protected readonly int someOtherDependency;
protected readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class FakeSpecialComponent : SpecialComponent
{
public FakeSpecialComponent(IComponentDependency dependency, int someOtherDependency)
: base(dependency, someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
}
But this doesn't seem ideal to me. Another option is to simply expose the dependencies as public
. While this would permit the test to assert that the dependencies used are correct, it also goes against my long held belief in keeping data as private as possible and only exposing the behavior.
public class SpecialComponent
{
public int SomeOtherDependency;
public IComponentDependency Sependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
Sependency = dependency;
SomeOtherDependency = someOtherDependency;
}
public void DoStuff()
{
Dependency.HelpInDoingStuff(SomeOtherDependency);
}
}
Concluding Thoughts
If the entire solution never actually references SpecialComponent
directly, but instead always references IComponent
, then is there any harm (or smelliness) in the second option of exposing the dependencies as public
get-only properties. But now I'm butting up against another long held belief in modifying the accessibility of members for the sole purpose of unit testing.
Question
Is there any harm in actually making the private readonly
fields into public
get-only properties on my concrete types? I'm trying to rationalize it as being OK since consumers of SpecialComponent
only reference IComponent
, so they won't have direct access to the data, but the tests could simply cast to SpecialComponent
and perform the desired assert statements.
Am I over thinking all of this? :)
EDIT: I've updated the above code samples to include method declarations and implementations for IComponent
to 'fill out' the example. As noted in the below comment, I could unit test that the IComponent
instance returned from SpecialComponentFactory.CreateComponent
behaves a certain way which would provide coverage in proving that the required dependencies were used, but this to me sounds like the least acceptable option since the unit tests for SpecialComponentFactory
would unnecessarily be testing SpecialComponent
's implementation, thereby giving it reasons to fail outside of it's own implementation and coupling the SpecialComponentFactory
tests to the behavior of SpecialComponent
c# unit-testing interface factory class-design
closed as primarily opinion-based by mjwills, Erik Philips, Tetsuya Yamamoto, Damien_The_Unbeliever, mhand Jan 4 at 11:05
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
|
show 3 more comments
Summary
Is there harm in exposing concrete class data as get-only public properties solely for the purposes of writing better unit tests?
Background
In general, I prefer to keep as much, if not all, of my data as private readonly
. This ensures consumers aren't bound to the data held but rather to the behaviors a type provides. One (potential) issue I've noticed recently is writing good unit tests for factory types that implement an interface. Consider the following illustrative example:
public interface IComponent
{
void DoStuff();
}
public interface IComponentDependency
{
void HelpInDoingStuff(int data);
}
public interface IFactory
{
IComponent CreateComponent(IComponentDependency dependency)
}
public class SpecialComponent : IComponent
{
private readonly int someOtherDependency;
private readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class SpecialComponentFactory : IFactory
{
private readonly int someOtherDependency;
public SpecialComponentFactory(int someOtherDependency)
{
this.someOtherDependency = someOtherDependency;
}
public IComponent CreateComponent(IComponentDependency dependency)
{
return new SpecialComponent(dependency, this.someOtherDependency);
}
}
When writing tests for SpecialComponentFactory
the only thing available publicly to test is that SpecialComponentFactory
returns an instance of SpecialComponent
. What if I'd also like to confirm that SpecialComponent
was indeed constructed with someOtherDependency
, or in fact, that he was constructed with the specified dependency
. To do this without reflection hacks we could make them protected
and subclass SpecialComponent
and then expose it publicly via a test fake:
public class SpecialComponent
{
protected readonly int someOtherDependency;
protected readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class FakeSpecialComponent : SpecialComponent
{
public FakeSpecialComponent(IComponentDependency dependency, int someOtherDependency)
: base(dependency, someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
}
But this doesn't seem ideal to me. Another option is to simply expose the dependencies as public
. While this would permit the test to assert that the dependencies used are correct, it also goes against my long held belief in keeping data as private as possible and only exposing the behavior.
public class SpecialComponent
{
public int SomeOtherDependency;
public IComponentDependency Sependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
Sependency = dependency;
SomeOtherDependency = someOtherDependency;
}
public void DoStuff()
{
Dependency.HelpInDoingStuff(SomeOtherDependency);
}
}
Concluding Thoughts
If the entire solution never actually references SpecialComponent
directly, but instead always references IComponent
, then is there any harm (or smelliness) in the second option of exposing the dependencies as public
get-only properties. But now I'm butting up against another long held belief in modifying the accessibility of members for the sole purpose of unit testing.
Question
Is there any harm in actually making the private readonly
fields into public
get-only properties on my concrete types? I'm trying to rationalize it as being OK since consumers of SpecialComponent
only reference IComponent
, so they won't have direct access to the data, but the tests could simply cast to SpecialComponent
and perform the desired assert statements.
Am I over thinking all of this? :)
EDIT: I've updated the above code samples to include method declarations and implementations for IComponent
to 'fill out' the example. As noted in the below comment, I could unit test that the IComponent
instance returned from SpecialComponentFactory.CreateComponent
behaves a certain way which would provide coverage in proving that the required dependencies were used, but this to me sounds like the least acceptable option since the unit tests for SpecialComponentFactory
would unnecessarily be testing SpecialComponent
's implementation, thereby giving it reasons to fail outside of it's own implementation and coupling the SpecialComponentFactory
tests to the behavior of SpecialComponent
c# unit-testing interface factory class-design
closed as primarily opinion-based by mjwills, Erik Philips, Tetsuya Yamamoto, Damien_The_Unbeliever, mhand Jan 4 at 11:05
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
1
a) This will almost certainly be closed as opinion based. b) My opinion is to make itpublic
(with basically the same reasoning as your text under Question).
– mjwills
Jan 4 at 5:12
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created classSpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.
– mhand
Jan 4 at 6:07
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09
|
show 3 more comments
Summary
Is there harm in exposing concrete class data as get-only public properties solely for the purposes of writing better unit tests?
Background
In general, I prefer to keep as much, if not all, of my data as private readonly
. This ensures consumers aren't bound to the data held but rather to the behaviors a type provides. One (potential) issue I've noticed recently is writing good unit tests for factory types that implement an interface. Consider the following illustrative example:
public interface IComponent
{
void DoStuff();
}
public interface IComponentDependency
{
void HelpInDoingStuff(int data);
}
public interface IFactory
{
IComponent CreateComponent(IComponentDependency dependency)
}
public class SpecialComponent : IComponent
{
private readonly int someOtherDependency;
private readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class SpecialComponentFactory : IFactory
{
private readonly int someOtherDependency;
public SpecialComponentFactory(int someOtherDependency)
{
this.someOtherDependency = someOtherDependency;
}
public IComponent CreateComponent(IComponentDependency dependency)
{
return new SpecialComponent(dependency, this.someOtherDependency);
}
}
When writing tests for SpecialComponentFactory
the only thing available publicly to test is that SpecialComponentFactory
returns an instance of SpecialComponent
. What if I'd also like to confirm that SpecialComponent
was indeed constructed with someOtherDependency
, or in fact, that he was constructed with the specified dependency
. To do this without reflection hacks we could make them protected
and subclass SpecialComponent
and then expose it publicly via a test fake:
public class SpecialComponent
{
protected readonly int someOtherDependency;
protected readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class FakeSpecialComponent : SpecialComponent
{
public FakeSpecialComponent(IComponentDependency dependency, int someOtherDependency)
: base(dependency, someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
}
But this doesn't seem ideal to me. Another option is to simply expose the dependencies as public
. While this would permit the test to assert that the dependencies used are correct, it also goes against my long held belief in keeping data as private as possible and only exposing the behavior.
public class SpecialComponent
{
public int SomeOtherDependency;
public IComponentDependency Sependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
Sependency = dependency;
SomeOtherDependency = someOtherDependency;
}
public void DoStuff()
{
Dependency.HelpInDoingStuff(SomeOtherDependency);
}
}
Concluding Thoughts
If the entire solution never actually references SpecialComponent
directly, but instead always references IComponent
, then is there any harm (or smelliness) in the second option of exposing the dependencies as public
get-only properties. But now I'm butting up against another long held belief in modifying the accessibility of members for the sole purpose of unit testing.
Question
Is there any harm in actually making the private readonly
fields into public
get-only properties on my concrete types? I'm trying to rationalize it as being OK since consumers of SpecialComponent
only reference IComponent
, so they won't have direct access to the data, but the tests could simply cast to SpecialComponent
and perform the desired assert statements.
Am I over thinking all of this? :)
EDIT: I've updated the above code samples to include method declarations and implementations for IComponent
to 'fill out' the example. As noted in the below comment, I could unit test that the IComponent
instance returned from SpecialComponentFactory.CreateComponent
behaves a certain way which would provide coverage in proving that the required dependencies were used, but this to me sounds like the least acceptable option since the unit tests for SpecialComponentFactory
would unnecessarily be testing SpecialComponent
's implementation, thereby giving it reasons to fail outside of it's own implementation and coupling the SpecialComponentFactory
tests to the behavior of SpecialComponent
c# unit-testing interface factory class-design
Summary
Is there harm in exposing concrete class data as get-only public properties solely for the purposes of writing better unit tests?
Background
In general, I prefer to keep as much, if not all, of my data as private readonly
. This ensures consumers aren't bound to the data held but rather to the behaviors a type provides. One (potential) issue I've noticed recently is writing good unit tests for factory types that implement an interface. Consider the following illustrative example:
public interface IComponent
{
void DoStuff();
}
public interface IComponentDependency
{
void HelpInDoingStuff(int data);
}
public interface IFactory
{
IComponent CreateComponent(IComponentDependency dependency)
}
public class SpecialComponent : IComponent
{
private readonly int someOtherDependency;
private readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class SpecialComponentFactory : IFactory
{
private readonly int someOtherDependency;
public SpecialComponentFactory(int someOtherDependency)
{
this.someOtherDependency = someOtherDependency;
}
public IComponent CreateComponent(IComponentDependency dependency)
{
return new SpecialComponent(dependency, this.someOtherDependency);
}
}
When writing tests for SpecialComponentFactory
the only thing available publicly to test is that SpecialComponentFactory
returns an instance of SpecialComponent
. What if I'd also like to confirm that SpecialComponent
was indeed constructed with someOtherDependency
, or in fact, that he was constructed with the specified dependency
. To do this without reflection hacks we could make them protected
and subclass SpecialComponent
and then expose it publicly via a test fake:
public class SpecialComponent
{
protected readonly int someOtherDependency;
protected readonly IComponentDependency dependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
public void DoStuff()
{
dependency.HelpInDoingStuff(someOtherDependency);
}
}
public class FakeSpecialComponent : SpecialComponent
{
public FakeSpecialComponent(IComponentDependency dependency, int someOtherDependency)
: base(dependency, someOtherDependency)
{
this.dependency = dependency;
this.someOtherDependency = someOtherDependency;
}
}
But this doesn't seem ideal to me. Another option is to simply expose the dependencies as public
. While this would permit the test to assert that the dependencies used are correct, it also goes against my long held belief in keeping data as private as possible and only exposing the behavior.
public class SpecialComponent
{
public int SomeOtherDependency;
public IComponentDependency Sependency;
public SpecialComponent(IComponentDependency dependency, int someOtherDependency)
{
Sependency = dependency;
SomeOtherDependency = someOtherDependency;
}
public void DoStuff()
{
Dependency.HelpInDoingStuff(SomeOtherDependency);
}
}
Concluding Thoughts
If the entire solution never actually references SpecialComponent
directly, but instead always references IComponent
, then is there any harm (or smelliness) in the second option of exposing the dependencies as public
get-only properties. But now I'm butting up against another long held belief in modifying the accessibility of members for the sole purpose of unit testing.
Question
Is there any harm in actually making the private readonly
fields into public
get-only properties on my concrete types? I'm trying to rationalize it as being OK since consumers of SpecialComponent
only reference IComponent
, so they won't have direct access to the data, but the tests could simply cast to SpecialComponent
and perform the desired assert statements.
Am I over thinking all of this? :)
EDIT: I've updated the above code samples to include method declarations and implementations for IComponent
to 'fill out' the example. As noted in the below comment, I could unit test that the IComponent
instance returned from SpecialComponentFactory.CreateComponent
behaves a certain way which would provide coverage in proving that the required dependencies were used, but this to me sounds like the least acceptable option since the unit tests for SpecialComponentFactory
would unnecessarily be testing SpecialComponent
's implementation, thereby giving it reasons to fail outside of it's own implementation and coupling the SpecialComponentFactory
tests to the behavior of SpecialComponent
c# unit-testing interface factory class-design
c# unit-testing interface factory class-design
edited Jan 4 at 11:06
mhand
asked Jan 4 at 5:08
mhandmhand
5891517
5891517
closed as primarily opinion-based by mjwills, Erik Philips, Tetsuya Yamamoto, Damien_The_Unbeliever, mhand Jan 4 at 11:05
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
closed as primarily opinion-based by mjwills, Erik Philips, Tetsuya Yamamoto, Damien_The_Unbeliever, mhand Jan 4 at 11:05
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
1
a) This will almost certainly be closed as opinion based. b) My opinion is to make itpublic
(with basically the same reasoning as your text under Question).
– mjwills
Jan 4 at 5:12
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created classSpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.
– mhand
Jan 4 at 6:07
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09
|
show 3 more comments
1
a) This will almost certainly be closed as opinion based. b) My opinion is to make itpublic
(with basically the same reasoning as your text under Question).
– mjwills
Jan 4 at 5:12
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created classSpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.
– mhand
Jan 4 at 6:07
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09
1
1
a) This will almost certainly be closed as opinion based. b) My opinion is to make it
public
(with basically the same reasoning as your text under Question).– mjwills
Jan 4 at 5:12
a) This will almost certainly be closed as opinion based. b) My opinion is to make it
public
(with basically the same reasoning as your text under Question).– mjwills
Jan 4 at 5:12
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created class
SpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.– mhand
Jan 4 at 6:07
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created class
SpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.– mhand
Jan 4 at 6:07
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09
|
show 3 more comments
1 Answer
1
active
oldest
votes
This is one of the symptoms of approaching unit tests literally.
I would say factory is implementation details of the class which uses IComponent
.
And factory would be tested through tests for that class.
I don't care how those tests categorized(unit, integration etc.) - I care only about is my tests slow to run or complex to setup.
So I will mock only things which will make my tests slow or complicated. The logic will be tested within application boundaries which keep tests fast.
For example in Web application it can be Controller -> Database(in-memory or mocked).
Consider unit as "unit of behaviour".
Writing unit tests only because every class should be tested - can be considered as wasting of time. Because any change in internal design will force me to rewrite unit tests or remove obsolete or writ new ones, only for class, which I think is usable at his moment.
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools likegit rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.
– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is one of the symptoms of approaching unit tests literally.
I would say factory is implementation details of the class which uses IComponent
.
And factory would be tested through tests for that class.
I don't care how those tests categorized(unit, integration etc.) - I care only about is my tests slow to run or complex to setup.
So I will mock only things which will make my tests slow or complicated. The logic will be tested within application boundaries which keep tests fast.
For example in Web application it can be Controller -> Database(in-memory or mocked).
Consider unit as "unit of behaviour".
Writing unit tests only because every class should be tested - can be considered as wasting of time. Because any change in internal design will force me to rewrite unit tests or remove obsolete or writ new ones, only for class, which I think is usable at his moment.
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools likegit rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.
– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
add a comment |
This is one of the symptoms of approaching unit tests literally.
I would say factory is implementation details of the class which uses IComponent
.
And factory would be tested through tests for that class.
I don't care how those tests categorized(unit, integration etc.) - I care only about is my tests slow to run or complex to setup.
So I will mock only things which will make my tests slow or complicated. The logic will be tested within application boundaries which keep tests fast.
For example in Web application it can be Controller -> Database(in-memory or mocked).
Consider unit as "unit of behaviour".
Writing unit tests only because every class should be tested - can be considered as wasting of time. Because any change in internal design will force me to rewrite unit tests or remove obsolete or writ new ones, only for class, which I think is usable at his moment.
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools likegit rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.
– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
add a comment |
This is one of the symptoms of approaching unit tests literally.
I would say factory is implementation details of the class which uses IComponent
.
And factory would be tested through tests for that class.
I don't care how those tests categorized(unit, integration etc.) - I care only about is my tests slow to run or complex to setup.
So I will mock only things which will make my tests slow or complicated. The logic will be tested within application boundaries which keep tests fast.
For example in Web application it can be Controller -> Database(in-memory or mocked).
Consider unit as "unit of behaviour".
Writing unit tests only because every class should be tested - can be considered as wasting of time. Because any change in internal design will force me to rewrite unit tests or remove obsolete or writ new ones, only for class, which I think is usable at his moment.
This is one of the symptoms of approaching unit tests literally.
I would say factory is implementation details of the class which uses IComponent
.
And factory would be tested through tests for that class.
I don't care how those tests categorized(unit, integration etc.) - I care only about is my tests slow to run or complex to setup.
So I will mock only things which will make my tests slow or complicated. The logic will be tested within application boundaries which keep tests fast.
For example in Web application it can be Controller -> Database(in-memory or mocked).
Consider unit as "unit of behaviour".
Writing unit tests only because every class should be tested - can be considered as wasting of time. Because any change in internal design will force me to rewrite unit tests or remove obsolete or writ new ones, only for class, which I think is usable at his moment.
edited Jan 4 at 8:53
answered Jan 4 at 8:48
FabioFabio
20.4k22048
20.4k22048
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools likegit rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.
– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
add a comment |
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools likegit rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.
– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools like
git rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.– mhand
Jan 4 at 11:00
Thanks for the comment. I don't disagree with your premise. Some projects, whether for better or worse, have requirements to maintain a certain level of unit test coverage. I overwhelmingly agree with your comments on test speed. I think it's imperative that an entire test suite runs in a matter of seconds, not minutes -- which makes tools like
git rebase <hash-ref> -ix 'script-to-run-tests'
exceedingly powerful. Also, I've found that if the test suite even takes a full minute, developers tend to either lose focus while running the tests or simply don't run them.– mhand
Jan 4 at 11:00
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
RE: only mocking things that make tests slow -- in your experience, do you find that changing/updating an implementation in one part of the code base often requires changing multiple, potentially unrelated, unit tests? I've experienced this on a previous project where it was too time consuming and/or darn near impossible to mock some of the components so we just didn't and often times small bug fixes required updating many seemingly unrelated tests. I suppose that experienced scarred me to far in the other direction :P
– mhand
Jan 4 at 11:02
add a comment |
1
a) This will almost certainly be closed as opinion based. b) My opinion is to make it
public
(with basically the same reasoning as your text under Question).– mjwills
Jan 4 at 5:12
@mjwills -- thanks for the comment -- and yes, I half anticipated it to be closed, but was hopeful that there was some reference in a book that supports my claims. Thank you for your opinion.
– mhand
Jan 4 at 5:30
The real problem here is you are storing values that aren't used, so you don't have a valid example. The point of a unit test is to validate a single method logic. Validating that a variable is set a value has no value.
– Erik Philips
Jan 4 at 5:33
@ErikPhilips - Storing values that aren't used? I think I was pretty clear that the example is purely illustrative. If you noticed, the interface definitions are empty and in the real code the dependencies are actually used, so I think your down vote is fairly unsubstantiated. If you prefer, I can add methods that use these values, but then again, I'm writing a unit test for the factory and I don't think that a unit test for the factory should test the behavior of the created class
SpecialComponent
, which would be required in order to confirm that certain dependencies were in fact used.– mhand
Jan 4 at 6:07
Well you answered your own question with the last sentence.
– Erik Philips
Jan 4 at 6:09