简体   繁体   中英

JMockit dynamic partial mock a constructor of the class under test

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 with Expectations(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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM