Reputation: 4088
So I read this documentation to understand how JMockit
supports dynamic partial mocking of a class.
As shown above, the
NonStrictExpectations(Object...)
constructor accepts one or more classes or objects to be partially mocked. (The same occurs withExpectations(Object...)
, which allows strict expectations on a partially mocked type.) If a Class object is given, the methods and constructors defined in that class are considered for mocking, as well as the methods and constructors of its super-classes; all instances of the specified class will be regarded as mocked instances. If, on the other hand, a regular instance is given, then only methods, not constructors, in the class hierarchy are considered for mocking; even more, only that particular instance will be mocked.
There's a mention that if we used the Expectations
with Class
objects, all its methods and constructors and those of its parents will be considered for mocking. What does being "considered" for mocking mean? That they will be eligible for mocking and for them to be mocked, we'll need to enclose them in the new Expectations(...)
block (I'd expect that to be the case, it's partial mocking after all)?
Also, there's no mention of how to dynamically partial mock the constructor of a class and do the initializations I wanted my way - in my case it's the class under test. Surely, it's not the $init
that I would have used in a MockUp
implementation? I don't think the @Tested
, @Injectable
combo would have worked, I don't have a constructor that takes parameters to initialize all the instance variables.
Of course I could build out a constructor just for unit testing needs, but adding such code is exactly what I'm trying to avoid.
Any example of how I'd go about doing this?
EDIT: prototype of a class that I'm trying to mock:
class Sample
{
Dependency dep;
// the constructor i'd like to mock out and set the dependencies (dep) myself
public Sample()
{
dep = new Dependency("i'm a nuisance");
}
// method to be tested
void doSomethingWithTheDependency()
{
// does a few things using dep
System.out.println(dep.getId());
}
}
If I could mock out the constructor to set the dep
myself, that would help me greatly. Of course, this is a classic example of a case that would have been a lot easier to deal with if I was "injecting" the dependency rather than instantiating like that, but such an "injection" here IMO would only aid testing, just nothing else. Which is why I'm looking to mock the constructor of Sample
class.
Upvotes: 1
Views: 1523
Reputation: 16380
This example is very easy to deal with:
@Test
public void mockInternalDependency(@Mocked final Dependency anyDep)
{
new NonStrictExpectations() {{ anyDep.getId(); result = "test"; }};
new Sample().doSomethingWithTheDependency();
new Verifications() {{
// verify invocations to "anyDep" here, if needed
}};
}
As you see, there is no need to worry about the constructor of Sample
, or its dep
field. If the class under test instantiated the dependency anywhere else, the test would still be the same.
Upvotes: 1