Reputation: 56894
Fairly new to the concept of unit testing here. I'm using Java (JUnit) but this is really a question that applies to any type of unit testing.
Say I have number of objects:
Widget
Foo
Fizz
Buzz
And they are all in the same package. Let's just say that Widget
has a run()
method that looks like this:
public void run() {
Foo foo = new Foo(true, 1);
Fizz fizz = FizzFactory.getInstance(Widget.class);
Buzz buzz = getBuzz();
int someData = fizz.process(buzz);
foo.execute(someData);
}
So here we have several objects (and their methods) being called inside of run()
. How does one actually go about unit testing ("mocking" or "stubbing" out Foo
, Fizz
and Buzz
) this method without crossing the grey line into integration testing?
Upvotes: 0
Views: 141
Reputation: 27222
If you're making static calls to create objects in your method you're likely "doing it wrong". Note that a constructor is just a special kind of static method.
Misko Hevery has number of very good posts on this topic.
If you want to be able to test your classes you need to be able to exchange your "business logic" with testing mocks or stubs. You do that by ensuring that constructors don't do real work, but rather just set up objects that have been constructed in other places.
If I were to refactor this to be testable I'd have something like so:
public class X {
public X(FooFactory ff , FizzFactory fz, BuzzFactory bf) {
_fooFactory = ff;
_fizzFactory = fz;
_buzzFactory = bf;
}
public void run() {
Foo foo = _fooFactory.newFoo(true,1);
Fizz fizz = _fizzFactory.getInstance(Widget.class);
Buzz buzz = _buzzFactory.getBuzz();
int someData = fizz.process(buzz);
foo.execute(someData);
}
}
Using the factories above (or subclasses that mock out the behavior) you've insulated the testing of X to just the methods it calls. You could set up expectations for the run method and test them, but not have to deal with fizz.process, say, connecting to a DB.
Note that not much is happening here, no branching, so the test would be fairly straightforward. The trick of not calling new in the constructor or static methods to create objects should carry over though.
A good keyword while looking for info about this is Dependency Injection.
Upvotes: 2
Reputation: 4146
My personal opinion is that, in this case, you have seperate tests for
Foo(bool, int)
FizzFactory.getInstance
getBuzz()
fizz.process()
and
foo.execute
run()
is an integration of all the above methods.
Upvotes: 0