Hãy xem xét một chữ ký phương thức như:
public String myFunction(String abc);
Mockito có thể giúp trả về cùng một chuỗi mà phương thức nhận được không?
Hãy xem xét một chữ ký phương thức như:
public String myFunction(String abc);
Mockito có thể giúp trả về cùng một chuỗi mà phương thức nhận được không?
Câu trả lời:
Bạn có thể tạo một câu trả lời trong Mockito. Giả sử, chúng ta có một giao diện có tên Ứng dụng với phương thức myFactor.
public interface Application {
public String myFunction(String abc);
}
Đây là phương pháp thử nghiệm với câu trả lời Mockito:
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"));
}
Kể từ Mockito 1.9.5 và Java 8, bạn cũng có thể sử dụng biểu thức lambda:
when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
. Và bạn cũng có thể sử dụng một tham chiếu phương thức và gọi phương thức thực.
Iterator<? extends ClassName>
gây ra tất cả các loại vấn đề trong một thenReturn()
câu lệnh.
when(foo(any()).thenAnswer(i -> i.getArguments()[0])
Nếu bạn có Mockito 1.9.5 trở lên, có một phương thức tĩnh mới có thể tạo Answer
đối tượng cho bạn. Bạn cần phải viết một cái gì đó như
import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
when(myMock.myFunction(anyString())).then(returnsFirstArg());
Hay cách khác
doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());
Lưu ý rằng returnsFirstArg()
phương thức này là tĩnh trong AdditionalAnswers
lớp, mới đối với Mockito 1.9.5; vì vậy bạn sẽ cần nhập tĩnh đúng.
when(...).then(returnsFirstArg())
, tôi đã nhầm lẫn đã when(...).thenReturn(returnsFirstArg())
chojava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
. này để sử dụng returnFirstArg. Ngoài ra, tôi có thể làm when(myMock.myFunction(any())).then(returnsFirstArg())
trong Mockito 2.20. *
Với Java 8, có thể tạo câu trả lời một dòng ngay cả với phiên bản cũ hơn của Mockito:
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
Tất nhiên điều này không hữu ích như việc sử dụng được AdditionalAnswers
đề xuất bởi David Wallace, nhưng có thể hữu ích nếu bạn muốn chuyển đổi đối số "nhanh chóng".
long
, điều này vẫn có thể làm việc với quyền anh và Long.class
?
Tôi đã có một vấn đề rất giống nhau. Mục đích là để chế nhạo một dịch vụ vẫn tồn tại các Đối tượng và có thể trả lại chúng bằng tên của chúng. Dịch vụ này trông như thế này:
public class RoomService {
public Room findByName(String roomName) {...}
public void persist(Room room) {...}
}
Dịch vụ giả sử dụng bản đồ để lưu trữ các thể hiện của Phòng.
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;
}
});
Bây giờ chúng tôi có thể chạy thử nghiệm của chúng tôi trên giả này. Ví dụ:
String name = "room";
Room room = new Room(name);
roomService.persist(room);
assertThat(roomService.findByName(name), equalTo(room));
assertNull(roomService.findByName("none"));
Với Java 8, câu trả lời của Steve có thể trở thành
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: Thậm chí ngắn hơn:
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"));
}
Đây là một câu hỏi khá cũ nhưng tôi nghĩ vẫn còn liên quan. Ngoài ra câu trả lời được chấp nhận chỉ hoạt động cho String. Trong khi đó, có Mockito 2.1 và một số nhập khẩu đã thay đổi, vì vậy tôi muốn chia sẻ câu trả lời hiện tại của mình:
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 sẽ trông như sau:
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
Tôi sử dụng một cái gì đó tương tự (về cơ bản là cách tiếp cận tương tự). Đôi khi thật hữu ích khi có một đối tượng giả trả về đầu ra được xác định trước cho các đầu vào nhất định. Điều đó diễn ra như sau:
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
}
}
}
);
Bạn có thể muốn sử dụng xác minh () kết hợp với ArgumentCaptor để đảm bảo thực thi trong thử nghiệm và ArgumentCaptor để đánh giá các đối số:
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
Giá trị của đối số rõ ràng có thể truy cập được thông qua đối số.getValue () để tiếp tục thao tác / kiểm tra / bất cứ điều gì.
Điều này hơi cũ, nhưng tôi đến đây vì tôi có cùng một vấn đề. Tôi đang sử dụng JUnit nhưng lần này là trong ứng dụng Kotlin với mockk. Tôi đang đăng một mẫu ở đây để tham khảo và so sánh với đối tác Java:
@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"))
}
Bạn có thể đạt được điều này bằng cách sử dụng ArgumentCaptor
Hãy tưởng tượng bạn có chức năng đậu như vậy.
public interface Application {
public String myFunction(String abc);
}
Sau đó, trong lớp kiểm tra của bạn:
//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.
}
});
HOẶC nếu bạn hâm mộ lambda chỉ cần làm:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture()))
.thenAnswer((invocation) -> param.getValue());
Tóm tắt: Sử dụng argumentcaptor, để nắm bắt tham số đã truyền. Sau đó trong câu trả lời trả về giá trị được bắt bằng cách sử dụng getValue.
This doesn´t work (anymore?).
tôi làm việc này. 2. Xin lỗi, tôi không rõ về điểm bạn đang cố gắng thực hiện. Câu trả lời là cụ thể cho câu hỏi của OP.