Aşağıdaki gibi bir yöntem imzası düşünün:
public String myFunction(String abc);
Mockito, yöntemin aldığı dizenin aynısını döndürmeye yardımcı olabilir mi?
Aşağıdaki gibi bir yöntem imzası düşünün:
public String myFunction(String abc);
Mockito, yöntemin aldığı dizenin aynısını döndürmeye yardımcı olabilir mi?
Yanıtlar:
Mockito'da bir Cevap oluşturabilirsiniz. Diyelim ki myFunction yöntemiyle Application adlı bir arayüzümüz var.
public interface Application {
public String myFunction(String abc);
}
İşte Mockito cevaplı test yöntemi:
public void testMyFunction() throws Exception {
Application mock = mock(Application.class);
when(mock.myFunction(anyString())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return (String) args[0];
}
});
assertEquals("someString",mock.myFunction("someString"));
assertEquals("anotherString",mock.myFunction("anotherString"));
}
Mockito 1.9.5 ve Java 8'den beri lambda ifadesini de kullanabilirsiniz:
when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
. Ayrıca bir yöntem referansı kullanabilir ve gerçek yöntemi çağırabilirsiniz.
Iterator<? extends ClassName>
bir thenReturn()
ifadede her türlü döküm sorununa neden olan dönüşleri çözer .
when(foo(any()).thenAnswer(i -> i.getArguments()[0])
Mockito 1.9.5 veya daha üst sürümünüz varsa, Answer
nesneyi sizin için yapabilen yeni bir statik yöntem vardır . Gibi bir şey yazmalısın
import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
when(myMock.myFunction(anyString())).then(returnsFirstArg());
Veya alternatif olarak
doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());
returnsFirstArg()
Yöntemin AdditionalAnswers
Mockito 1.9.5 için yeni olan sınıfta statik olduğunu unutmayın ; böylece doğru statik içe aktarmaya ihtiyacınız olacaktır.
when(...).then(returnsFirstArg())
Yanlışlıkla when(...).thenReturn(returnsFirstArg())
verdijava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
. returnFirstArg kullanmak için bunu. Ayrıca, when(myMock.myFunction(any())).then(returnsFirstArg())
Mockito 2.20 de yapabilirim . *
Java 8 ile Mockito'nun eski sürümüyle bile tek satırlık bir yanıt oluşturmak mümkündür:
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
Tabii ki bu, AdditionalAnswers
David Wallace'ın önerdiği kadar kullanışlı değil , ancak "anında" argümanını dönüştürmek istiyorsanız yararlı olabilir.
long
, bu hala boks ve ile çalışabilir Long.class
mi?
Çok benzer bir sorun yaşadım. Amaç, Nesneleri sürdürebilen ve isimleriyle geri gönderebilen bir hizmeti taklit etmekti. Hizmet şöyle görünür:
public class RoomService {
public Room findByName(String roomName) {...}
public void persist(Room room) {...}
}
Hizmet sahte, Oda örneklerini saklamak için bir harita kullanır.
RoomService roomService = mock(RoomService.class);
final Map<String, Room> roomMap = new HashMap<String, Room>();
// mock for method persist
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 0 && arguments[0] != null) {
Room room = (Room) arguments[0];
roomMap.put(room.getName(), room);
}
return null;
}
}).when(roomService).persist(any(Room.class));
// mock for method findByName
when(roomService.findByName(anyString())).thenAnswer(new Answer<Room>() {
@Override
public Room answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 0 && arguments[0] != null) {
String key = (String) arguments[0];
if (roomMap.containsKey(key)) {
return roomMap.get(key);
}
}
return null;
}
});
Şimdi bu sahte testlerimizi yapabiliriz. Örneğin:
String name = "room";
Room room = new Room(name);
roomService.persist(room);
assertThat(roomService.findByName(name), equalTo(room));
assertNull(roomService.findByName("none"));
Java 8 ile Steve'in cevabı olabilir
public void testMyFunction() throws Exception {
Application mock = mock(Application.class);
when(mock.myFunction(anyString())).thenAnswer(
invocation -> {
Object[] args = invocation.getArguments();
return args[0];
});
assertEquals("someString", mock.myFunction("someString"));
assertEquals("anotherString", mock.myFunction("anotherString"));
}
EDIT: Daha da kısa:
public void testMyFunction() throws Exception {
Application mock = mock(Application.class);
when(mock.myFunction(anyString())).thenAnswer(
invocation -> invocation.getArgument(0));
assertEquals("someString", mock.myFunction("someString"));
assertEquals("anotherString", mock.myFunction("anotherString"));
}
Bu oldukça eski bir soru ama yine de alakalı olduğunu düşünüyorum. Ayrıca kabul edilen cevap sadece String için çalışır. Bu arada Mockito 2.1 var ve bazı ithalatlar değişti, bu yüzden mevcut cevabımı paylaşmak istiyorum:
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@Mock
private MyClass myClass;
// this will return anything you pass, but it's pretty unrealistic
when(myClass.myFunction(any())).then(returnsFirstArg());
// it is more "life-like" to accept only the right type
when(myClass.myFunction(any(ClassOfArgument.class))).then(returnsFirstArg());
MyClass.myFunction şöyle görünecektir:
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
Benzer bir şey kullanıyorum (temelde aynı yaklaşım). Bazen, sahte giriş nesnesinin belirli girişler için önceden tanımlanmış bir çıktı döndürmesi yararlı olur. Bu şöyle:
private Hashtable<InputObject, OutputObject> table = new Hashtable<InputObject, OutputObject>();
table.put(input1, ouput1);
table.put(input2, ouput2);
...
when(mockObject.method(any(InputObject.class))).thenAnswer(
new Answer<OutputObject>()
{
@Override
public OutputObject answer(final InvocationOnMock invocation) throws Throwable
{
InputObject input = (InputObject) invocation.getArguments()[0];
if (table.containsKey(input))
{
return table.get(input);
}
else
{
return null; // alternatively, you could throw an exception
}
}
}
);
Testte yürütmeyi sağlamak için verify () öğesini ArgumentCaptor ile ve argümanları değerlendirmek için ArgumentCaptor ile birlikte kullanmak isteyebilirsiniz:
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
Argümanın değerine, daha fazla manipülasyon / kontrol / ne olursa olsun argument.getValue () aracılığıyla açıkça erişilebilir.
Bu biraz eski, ama buraya geldim çünkü aynı sorunu yaşadım. JUnit kullanıyorum ama bu sefer mockk ile bir Kotlin uygulamasında. Burada Java muadili ile referans ve karşılaştırma için bir örnek gönderiyorum:
@Test
fun demo() {
// mock a sample function
val aMock: (String) -> (String) = mockk()
// make it return the same as the argument on every invocation
every {
aMock.invoke(any())
} answers {
firstArg()
}
// test it
assertEquals("senko", aMock.invoke("senko"))
assertEquals("senko1", aMock.invoke("senko1"))
assertNotEquals("not a senko", aMock.invoke("senko"))
}
Bunu ArgumentCaptor kullanarak yapabilirsiniz
Fasulye fonksiyonuna sahip olduğunuzu düşünün.
public interface Application {
public String myFunction(String abc);
}
Sonra test sınıfınızda:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return param.getValue();//return the captured value.
}
});
VEYA lambda hayranıysanız yapmanız gerekenler:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture()))
.thenAnswer((invocation) -> param.getValue());
Özet: Geçirilen parametreyi yakalamak için argumentcaptor kullanın. Daha sonra yanıt olarak getValue kullanılarak yakalanan değeri döndürün.
This doesn´t work (anymore?).
. 2. Üzgünüm, yapmaya çalıştığınız noktada net değilim. Cevap OP'nin sorusuna özeldir.