Constructor in a spy object, can they be stubbed?

1,219 views
Skip to first unread message

Max

unread,
May 31, 2010, 10:52:16 AM5/31/10
to moc...@googlegroups.com
Hi everyone,

I got a question about stubbing constructors. I'm working with legacy code, adding a new feature and writing tests to verify *my* implementation. The problem is I can't create a real object in the test because there's an instantiation of another object in its constructor.

I moved that instantiation into its own protected factory method so I could mock the instantiated object.

So before it looked like this,

class DiagBuild
{
  private DiagnosticsXMLDBExportParser _databaseController = null;

  public DiagBuild() {
    _databaseController = new DiagnosticsXMLDBExportParser();
  }

  public void populateSystemEntities(Device device, String projectName)  {
    // Method I wanna test
  }
}

Now it looks like this,

class DiagBuild
{
  private DiagnosticsXMLDBExportParser _databaseController = null;

  public DiagBuild() {
    _databaseController = createDiagnosticsXMLDBExportParser();
  }

  protected DiagnosticsXMLDBExportParser createDiagnosticsXMLDBExportParser() {
    return new DiagnosticsXMLDBExportParser();
  }

  public void populateSystemEntities(Device device, String projectName)  {
    // Method I wanna test
  }
}

So, now I can create a spy for DiagBuild and stub the createDiagnosticsXMLDBExportParser() to return mocked DiagnosticsXMLDBExportParser. But the problem is you need to create an instance of a real object before calling the spy() method and since the constructor is calling the factory method it'll create an instance of the DiagnosticsXMLDBExportParser before the spy is even created. This causes problems since the DiagnosticsXMLDBExportParser initialises some stuff I don't want, in fact it throws an exception at the moment because it requires some Eclipse specific stuff to be initialized.

An obvious and probably most elegant solution would be the dependancy injection but not in this case since DiagBuild is not instantiated direcly. It is created as an extention point internally inside Eclipse.

Any idea what I should do or how I can stub the constructor? May be even some quick refactoring tip to get around it. I cannot refactor it too much though.The release is in a couple of weeks. ;)

Thanks,
Max.

James Carr

unread,
May 31, 2010, 11:03:05 AM5/31/10
to moc...@googlegroups.com
You should inject the dependency rather than try to stub the
constructor. One way I often do this if it's something like your
talking about where something out of my control constructs the object
I provide a default constructor with the dependency hard coded. Like
this:

class DiagBuild
{
private DiagnosticsXMLDBExportParser _databaseController = null;

public DiagBuild() {
this(new DiagnosticsXMLDBExportParser());
}
public DiagBuild(DiagnosticsXMLDBExportParser parser) {
_databaseController = parser;
}

> --
> You received this message because you are subscribed to the Google Groups
> "mockito" group.
> To post to this group, send email to moc...@googlegroups.com.
> To unsubscribe from this group, send email to
> mockito+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/mockito?hl=en.
>

Graham Allan

unread,
May 31, 2010, 11:05:33 AM5/31/10
to moc...@googlegroups.com
> An obvious and probably most elegant solution would be the dependancy
> injection but not in this case since DiagBuild is not instantiated
> direcly. It is created as an extention point internally inside Eclipse.

Why not have a second constructor which uses this technique? It would allow
you to test your code and match Eclipse's requirements simultaneously.

Regards,
Graham

Max

unread,
May 31, 2010, 11:12:05 AM5/31/10
to moc...@googlegroups.com
I think it's time for me to go home. Totally forgot about overloading constructors. Thanks very much guys for reminding me. ;)



--
Reply all
Reply to author
Forward
0 new messages