How to write unit test using mock object?

The more I read the layout, the more I get confused ...

I have a classA eat () method that calls FatDude eatThemAll () class

public class classA { FatDude dude = new FatDude(); public String eat() { String result = dude.eatThemAll(); } } public class FatDude { public String eatThemAll() { return "never full"; } } 

Now I want to test the classA eat () method, mocking the FatDude class.

 public class MockFatDude extends FatDude { //override public String eatThemAll() { return "very full"; } } ------------- test -------------- public class DoTest { public void runTest() { classA cl = new ClassA(); String out = cl.eat(); assertEqual(out, "very full"); } } 

This DoTest runTest () will not use the MockFatDude class. One way I can think of is to change the code to pass the FatDude method to the eat () method of class A:

 public class classA { public String eat(FatDude dude) { String result = dude.eatThemAll(); } } 

Then change my testing method to:

 public class DoTest { public void runTest() { classA cl = new ClassA(); String out = cl.eat(new MockFatDude()); assertEqual(out, "very full"); } } 

But, as you can see, I had to change the source code to satisfy my need. Is it correct? What if I am not allowed to modify the source code? I know if I am applying the TDD concept, it is fine to change the source code, but I would like to hear some opinion or advice if what I showed above is the right way.

+4
source share
2 answers

Mocking and the Dependency Inversion Principle (DIP) go hand in hand, and in most languages, Mocks works best by decoupling classes using interfaces.

In your case, this will work without the need to change the code: (Change: I mean, in the future, if you create your application in this way, you will not need to change the code to mock dependencies :))

  • IDude Abstract Interface
  • The specific FatDude (and MockFatDude) classes must implement the IDude interface.
  • provides a mechanism for an IDude instance to be "installed" or injected into classA - Injection Dependency (constructor or get / sets); or the Locator Service template is best (to replace a specific class)

Also note that many of the mocking frameworks actually allow you to create a Mock class class on the fly (see MoQ et al.), So you can create MockFatDude functionality directly in the unit test.

+4
source

Yes. You stumbled upon a good design directly because of your unit test. If you look more closely, you will see that you have removed the link between classA and FatDude. FatDude can now be an interface for behavior that is passed on when needed. ClassA doesn't need to know what type of FatDude it gets, or how to build FatDude (with cheeseburgers?).

Your decision is exactly what I would do. There is nothing wrong with changing the code to host the TDD if you understand the reasons and advantages / disadvantages for making such changes.

+2
source

All Articles