Java test if method is called

How can I know if a method was invoked on the unit under test?

I’m writing a new class ( Derived ), in TDD, using mockito and I have the following case: Class Base:

public abstract class Base < //. protected final T baseCreate(T entity)< // implementation >> 
public class Derived extends Base  < //. public MyObject create(MyObject entity)< baseCreate(entity); //This is what I want the implementation to be >> 

When I came to write a test the will force me to invoke the baseCreate method — I failed to understand how to do that. Is there a way, using mockito, to verify that the create(. ) method in Derived invokes the baseCreate(. ) method in the Base class? Thanks.

3 Answers 3

Unit tests are to test the behavior of the class, not its implementation. So you should not concern yourself with whther the Base ‘s baseCreate() is called explicitly, rather wheter calling Derived ‘s cerate() does exactly as you expect from an external observer’s perspective

Hi Attila, Thanks for the answer, but since I’m writing in TDD, I need to write the implementation of the Derived class only when a test fails. So, in that case, the implementation can also be return null; and the test will still pass.

So you need to test for a condition that is true when the Base.baseCreate() is called and false when it is not

Читайте также:  Css разный размер шрифта

Attila is right for most cases. What you want to test is that create actually does what you think it should do, not how it does it. The case you have here sounds like, «I already know that baseCreate does what I want it to do, so I don’t want to re-test that, just that it gets called.» This could be the case, but if so, then your superclass is really more of a collaborator. It’s part of the reason to favor delegation over inheritance. Nonetheless, sometimes it is difficult to go back and change that design decision, so you have to test what you have.

You should still favor just checking that «create» does what you want it to do on the whole, but you might have a case where baseCreate is really doing a lot of stuff that requires a lot of set up of collaborators and such which makes it difficult and brittle to test. In that case, you would want to use a «spy». A spy wraps a «real» object and delegates to the real method calls unless you specifically create another expectation.

If you could make baseCreate public, you could use Mockito like this:

@RunWith(MockitoJUnitRunner.class) // We prepare PartialMockClass for test because it's final or we need to mock private or static methods public class YourTestCase < @Spy private Derived classUnderTest = new Derived(); @Test public void privatePartialMockingWithPowerMock() < MyObject myObject = new MyObject(); when(classUnderTest.baseCreate(myObject)).thenReturn(myObject); // execute your test classUnderTest.create(myObject); verify(classUnderTest).baseCreate(myObject); >> 

If you can’t make baseCreate public, I think you could use PowerMock. It lets you verify private methods, but I don’t think there would be any reason it couldn’t do protected methods, too.

@RunWith(PowerMockRunner.class) // We prepare PartialMockClass for test because it's final or we need to mock private or static methods @PrepareForTest(Derived.class) public class YourTestCase < @Test public void testCreate() < Derived classUnderTest = PowerMockito.spy(new Derived()); MyObject myObject = new MyObject(); // use PowerMockito to set up your expectation PowerMockito.doReturn(myObject).when(classUnderTest, "baseCreate", myObject); // execute your test classUnderTest.create(myObject); // Use PowerMockito.verify() to verify result PowerMockito.verifyPrivate(classUnderTest).invoke("baseCreate", myObject); >> 

Источник

JUnit — test that a method has been called

I’m new to unit testing, and I’m trying to test that a method has been called. The method in question doesn’t return anything.

public void example (boolean foo) < if (foo) < processFoo(foo); >else if (foo==false) < processSomethingElse(foo); >> 

I want to be able to test that the processFoo method is being called, but I don’t know how to do that. If mocking is required, then I have to use JMockit . Thanks!

You can create spy of a class under the test throwing some exception when processFoo method is being called. If you catch this exception, everything is ok, otherwise this method hadn’t been called.

Duncan, I know, this doesn’t exactly match the code I’m using (which is for work so I can’t directly copy and paste) it’s actually not a boolean, but this seemed like the easiest way to explain the question 🙂

4 Answers 4

Sorry I’m a little late to the party, but I have a couple of ideas for you.

First, you mention that one option is to use JMockit—that’s great as it gives you a lot of flexibility. If you use JMockit, then the visibility of your processFoo() method doesn’t much matter. Let’s see what that might look like:

public class Subject < public void example (boolean foo) < if (foo) < processFoo(foo); >else if (foo==false) < processSomethingElse(foo); >> private void processFoo(boolean b) < System.out.println("b = " + b); >private void processSomethingElse(boolean bb) < System.out.println("bb b = " + b); >private void processSomethingElse(boolean bb) < System.out.println("bb mt24"> 
)" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this answer" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter devto" data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share
)" title="">Improve this answer
answered Dec 23, 2014 at 20:58
Add a comment |
0

You could use a counter variable in your class and increment it whenever the method is called, or use a print statement. If you don't have access to the processFoo method, a simple approach would be to do this at the time that processFoo is called in another method, if that's the only place where it can possibly be called.

For example:

public static int processFooCalls = 0; // . public void example (boolean foo) < if (foo) < processFoo(foo); processFooCalls += 1; // and/or System.out.println("processFoo method was called"); >// . > public static void main (String[] args) < // main routine here. System.out.println("'processFoo' was called " + processFooCalls + " times."); >

If processFoo can be called elsewhere, and you need to consider this possibility as well, then you'll need to have access to the processFoo code in order to do this, e.g.:

void processFoo( boolean b ) < // increment number of times processFoo was called here, and/or print, as follows processFooCalls += 1; System.out.println("called processFoo method!"); /* some functionality */ >

Источник

Junit to test if the method call is made

I've a transaction class with a validate method. There is a condition in the method that when satisfied will not be calling an alert notification method, which, on the other hand, will only be called when the check condition failed (if condition is false, call the alert and notify the user). I want to test with a JUnit, if that alert method get's called or not. Could someone advise how to proceed, as I'm new to JUnits.

4 Answers 4

Look at mocking libraries. In Mockito it will be like

 Notifier mock = Mockito.mock(Notifier.class); ClassUnderTest myClass = new ClassUnderTest(mock); myClass.doSomething(-1); Mockito.verify(mock).notification(Mockito.eq("Negative value passed!")); myClass.doSomething(100); Mockito.verifyNoMoreInteractions(mock); 

Thanks for the reply. so I should be having the condition in my Junit method and then call the method from within the condition and mock the method call?

Use the Mockito framework. This framework makes your kind of testing much easier.

You can use the verify method:

//Check if called once verify(dependency, times(1)).yourMethod() 

This is not really an answer as is. Why don't you add the mockito code for verifying that a method is called and I'll give you a +1.

From your question it is not clear whether or not the alert notification method belongs to the same class you are testing.

If the alert notification method is in a different class than the method you are testing, you can use a mocking library like Mockito to verify the method call, as suggested by other answers.

If, on the other hand, the notification method is in the same class as the validation method, I would advice to not verify the call to the notification method, but to verify the output of this method (you probably want to use a mocking library for this as well, but to verify method calls on any other objects used to create the alert)

A third possibility is that both methods are in the same class, but you really only want to test that the notification method gets called and not its output, because you feel that notification is a different function that you want to test separately. This would be a sign that your class may be doing too many things, and that it may be best to refactor so that these methods end up in separate classes.

Источник

Test that method was called

How do I test that when I call write("hello") , System.out.println("hello") is called? And also, is this unit test even worth it?

4 Answers 4

As for whether it is worth testing, it depends on why your are outputting. I usually do test System.out calls when writing command line utilities because that is the user interface and the text output matters. It's not even hard to do - just regular Java code.

The below technique shows how you can capture the values of System.out. You don't even need a mock framework. Note that it stores the "real" System.out so it can put it back at the end. If you don't do this, your other tests/code can quickly become confusing.

import static org.junit.Assert.*; import java.io.*; import org.junit.*; public class ConsoleHandlerTest < private PrintStream originalSysOut; private ByteArrayOutputStream mockOut; @Before public void setSysOut() < originalSysOut = System.out; mockOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(mockOut)); >@After public void restoreSysOut() < System.setOut(originalSysOut); >@Test public void outputIsCorrect() < new ConsoleHandler().write("hello"); assertEquals("message output", "hello".trim(), mockOut.toString().trim()); >> 

I changed "hellow" to "hello" because I thought it was a typo. That might be why. Or it could be a difference in linebreak. If not, show the actual text from the assertion failure. That will say what the comparison is failing on. (I ran this code on my machine so it definitely works somewhere)

No, this unit test is not worth the time or the disk space. Unit testing is to make sure you get logic right. If there's no logic, there is nothing to be gained from the test. Its cost-benefit ratio is infinite.

You should unit test a method if it has branching logic, loops, or exception handling. But if all it does is call another method, then forget it. The best way to find out whether method X calls method Y is to look at the code.

Having said that, if you do insist on testing this, you should use the System.setOut method, passing a ByteArrayOutputStream that you've wrapped in a PrintStream , and then verify the contents of the underlying byte[] at the end.

Источник

Оцените статью