Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock object construction?

Is there a way to mock object construction using JMock in Java?

For example, if I have a method as such:

public Object createObject(String objectType) {
    if(objectType.equals("Integer") {
        return new Integer();
    } else if (objectType.equals("String") {
        return new String();
    }
}

...is there a way to mock out the expectation of the object construction in a test method?

I'd like to be able to place expectations that certain constructors are being called, rather than having an extra bit of code to check the type (as it won't always be as convoluted and simple as my example).

So instead of:

assertTrue(a.createObject() instanceof Integer);

I could have an expectation of the certain constructor being called. Just to make it a bit cleaner, and express what is actually being tested in a more readable way.

Please excuse the simple example, the actual problem I'm working on is a bit more complicated, but having the expectation would simplify it.


For a bit more background:

I have a simple factory method, which creates wrapper objects. The objects being wrapped can require parameters which are difficult to obtain in a test class (it's pre-existing code), so it is difficult to construct them.

Perhaps closer to what I'm actually looking for is: is there a way to mock an entire class (using CGLib) in one fell swoop, without specifying every method to stub out?

So the mock is being wrapped in a constructor, so obviously methods can be called on it, is JMock capable of dynamically mocking out each method?

My guess is no, as that would be pretty complicated. But knowing I'm barking up the wrong tree is valuable too :-)

like image 789
Grundlefleck Avatar asked Sep 18 '08 12:09

Grundlefleck


People also ask

Can I mock a constructor?

0, we can now mock Java constructors with Mockito. This allows us to return a mock from every object construction for testing purposes. Similar to mocking static method calls with Mockito, we can define the scope of when to return a mock from a Java constructor for a particular Java class.

How do you call a mock method in a constructor?

Faking static methods called in a constructor is possible like any other call. if your constructor is calling a method of its own class, you can fake the call using this API: // Create a mock for class MyClass (Foo is the method called in the constructor) Mock mock = MockManager. Mock<MyClass>(Constructor.

Can we mock objects?

mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called. We don't need to do anything else to this method before we can use it. We can use it to create mock class fields, as well as local mocks in a method.


3 Answers

The only thing I can think of is to have the create method on at factory object, which you would than mock.

But in terms of mocking a constructor call, no. Mock objects presuppose the existence of the object, whereas a constructor presuppose that the object doesn't exist. At least in java where allocation and initialization happen together.

like image 59
sblundy Avatar answered Oct 24 '22 07:10

sblundy


jmockit can do this.

See my answer in https://stackoverflow.com/questions/22697#93675

like image 43
Kris Pruden Avatar answered Oct 24 '22 06:10

Kris Pruden


Alas, I think I'm guilty of asking the wrong question.

The simple factory I was trying to test looked something like:

public Wrapper wrapObject(Object toWrap) {
    if(toWrap instanceof ClassA) {
        return new Wrapper((ClassA) toWrap);
    } else if (toWrap instanceof ClassB) {
        return new Wrapper((ClassB) toWrap);
    } // etc

    else {
        return null;
    }
}

I was asking the question how to find if "new ClassAWrapper( )" was called because the object toWrap was hard to obtain in an isolated test. And the wrapper (if it can even be called that) is kind of weird as it uses the same class to wrap different objects, just uses different constructors[1]. I suspect that if I had asked the question a bit better, I would have quickly received the answer:

"You should mock Object toWrap to match the instances you're testing for in different test methods, and inspect the resulting Wrapper object to find the correct type is returned... and hope you're lucky enough that you don't have to mock out the world to create the different instances ;-)"

I now have an okay solution to the immediate problem, thanks!

[1] opening up the question of whether this should be refactored is well out of the scope of my current problem :-)

like image 32
Grundlefleck Avatar answered Oct 24 '22 08:10

Grundlefleck