How to test(mock) object that uses external API (Jama Software)

空扰寡人 提交于 2020-02-08 02:36:53

问题


I encountered a problem while trying to test Class, which uses external API -

Jama Software

. Let's say there is a ClassA. It has 2 methods,that I want to test using JUnit. Both methods have ClassB as an argument.

ClassB is belonging to another API. I can see it's methods but the implementation details are not available.(compiled code). The question is: How can I mock this classes to make TestClass isolated? I know that in Mockito there is an option to hardcode responses. Is there any better/cleaner way of doing this, so I don't need to manually configure mock objects? I would be grateful for any advices on that topic.


回答1:


A good read about mocking from another answer.

The point of using the mock with its methods is to isolate it from its dependencies. Mocking arguments may seem dirty or un-fancy, but it's designed to allow you to test the expectations of the mocked class. In this case, you assume that whatever your service ClassB is, works as intended (or not, if you expect exceptions as well). In this case, we are testing a single unit ClassA and assume that ClassB is correct.

I'll go ahead and make a more concrete example, similar to the waiter/chef example above.

Let's say your ClassA is a CookingPot and your ClassB is a Pantry. Any time you interact with the Pantry to getPasta, it tries to send you Pasta. If it has no Pasta, it returns null.

Pantry is a fancy Pantry. It has a table storing its contents, so you don't know if it has or doesn't have Pasta. This is "complex" in the real world, but this isn't our Pantry. We have no idea how it works, just that it either returns Pasta or it doesn't. We don't know the logic, nor do we have to. We know what it does, so if we want to make sure we can add pasta to our pot, we can use a mock Pantry that acts the same way, without having the fancy bells whistles the real one does.

Pantry also has a bunch of other methods, such as allowing you to add your leftover Pasta back to the shelf. You have no idea how the smart Pantry puts the pasta back in, but you don't need to model that, because Mockito is fine with void calls regardless.

If ClassB were to change, these tests might still pass, but you'd catch the issue in integration tests and say "hmm, my class still works, but something is up with the new Pantry so I need to redo the class, and rewire the tests."

CookingPot {
    void addPasta(Pantry pantry) {
        Pasta p = pantry.getPasta();
        System.out.println("Added " + p.toString() + " to the pot!"); 
        //fancy actions that use up some of the Pasta
        pantry.add(p); //return the pasta
    }
}

Pantry {
    Pasta getPasta(); //we have no idea what this does in actuality
}


@Test(expected = NullPointerException.class)
public void testAddPastaButNoPastaLeft() {
    Pantry mockPantry = mock(Pantry.class);

    CookingPot cookingPot = new CookingPot();
    cookingPot.addPasta(mockPantry);
    //we should probably have checked if there was pasta before 
    //attempting to add imaginary pasta
}

@Test
public void testAddPasta() {
    Pantry mockPantry = mock(Pantry.class);
    when(mockPantry.getBaz()).thenReturn(new Pasta());

    CookingPot cookingPot = new CookingPot();
    cookingPot.addPasta(mockPantry);
}


来源:https://stackoverflow.com/questions/37947075/how-to-testmock-object-that-uses-external-api-jama-software

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!