Java I';我需要知道如何在When()mockito方法中放置方法的接口
我试图在Android Studio中用mockito模拟一个方法,但是presenter类中的一个方法需要一个接口作为参数,但是,当我调用mockito的when()中的方法时,它无法识别接口。请参阅以下代码: 这是我的MVP代码示例 签约合同界面:Java I';我需要知道如何在When()mockito方法中放置方法的接口,java,android,mockito,Java,Android,Mockito,我试图在Android Studio中用mockito模拟一个方法,但是presenter类中的一个方法需要一个接口作为参数,但是,当我调用mockito的when()中的方法时,它无法识别接口。请参阅以下代码: 这是我的MVP代码示例 签约合同界面: public interface SignUpContract { interface view{ void showSignInScreen(); void onError(int code, String message);
public interface SignUpContract {
interface view{
void showSignInScreen();
void onError(int code, String message);
}
interface model{
interface onFinish<R>{
void onResponse(R data);
void onError(String error);
}
void trySignIn(onFinish onFinish, String name, String password);
}
interface presenter{
void handleSignInButtonClick(String username, String password);
}
}
SignUpRepository:
public class SignUpModel implements SignUpContract.model {
SignUpRepository repository;
public SignUpModel(){}
@Override
public void trySignIn(onFinish onFinish, String name, String password){
repository = new SignUpRepository();
String result = repository.signInUser(name, password);
if(!result.isEmpty()){
onFinish.onResponse(result);
} else {
onFinish.onError("Has error ocurred during the operation");
}
}
}
public class SignUpRepository {
public String signInUser(String username, String password){
String data = "Someone";
return data;
}
}
public class SignUpPresenter implements SignUpContract.presenter,
SignUpContract.model.onFinish {
SignUpContract.view view;
SignUpContract.model model;
public SignUpPresenter(SignUpContract.view view, SignUpContract.model model){
this.view = view;
this.model = model;
}
@Override
public void handleSignInButtonClick(String username, String password) {
try{
model.trySignIn(this, username, password);
}catch (Exception e){
Log.d("",e.getMessage());
}
}
@Override
public void onResponse(Object data) {
view.showSignInScreen();
}
@Override
public void onError(String error) {
view.onError(1, error);
}
}
签名者:
public class SignUpModel implements SignUpContract.model {
SignUpRepository repository;
public SignUpModel(){}
@Override
public void trySignIn(onFinish onFinish, String name, String password){
repository = new SignUpRepository();
String result = repository.signInUser(name, password);
if(!result.isEmpty()){
onFinish.onResponse(result);
} else {
onFinish.onError("Has error ocurred during the operation");
}
}
}
public class SignUpRepository {
public String signInUser(String username, String password){
String data = "Someone";
return data;
}
}
public class SignUpPresenter implements SignUpContract.presenter,
SignUpContract.model.onFinish {
SignUpContract.view view;
SignUpContract.model model;
public SignUpPresenter(SignUpContract.view view, SignUpContract.model model){
this.view = view;
this.model = model;
}
@Override
public void handleSignInButtonClick(String username, String password) {
try{
model.trySignIn(this, username, password);
}catch (Exception e){
Log.d("",e.getMessage());
}
}
@Override
public void onResponse(Object data) {
view.showSignInScreen();
}
@Override
public void onError(String error) {
view.onError(1, error);
}
}
这是我的测试:
@RunWith(MockitoJUnitRunner.class)
public class SignUpPresenterTest {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
@Mock SignUpContract.model model;
@Mock SignUpContract.model.onFinish listener;
@Mock SignUpContract.view view;
@InjectMocks SignUpPresenter SUT;
@Before
public void setUp() throws Exception {
SUT = new SignUpPresenter(view, model);
}
public void success() throws Exception {
**when(model.trySignIn(any(SignUpContract.model.onFinish.class), any(String.class), any(String.class))).then(SUT.onResponse(1));**
}
@Test
public void try_signin_success() throws Exception{
success();
ArgumentCaptor<String> ac = ArgumentCaptor.forClass(String.class);
SUT.handleSignInButtonClick(USERNAME, PASSWORD);
verify(model, times(1)).trySignIn(any(SignUpContract.model.onFinish.class), ac.capture(), ac.capture());
List<String> captures = ac.getAllValues();
Assert.assertThat(captures.get(0), is(USERNAME));
Assert.assertThat(captures.get(1), is(PASSWORD));
verify(view).showSignInScreen();
}
}
@RunWith(MockitoJUnitRunner.class)
公共类SignupPresentTest{
公共静态最终字符串USERNAME=“USERNAME”;
公共静态最终字符串PASSWORD=“PASSWORD”;
@模拟签约合同模型;
@模拟SignUpContract.model.onFinish侦听器;
@Mock-SignUpContract.view视图;
@注射mock-SignUpPresenter-SUT;
@以前
public void setUp()引发异常{
SUT=新的SignUpPresenter(视图、模型);
}
public void success()引发异常{
**当(model.trySignIn(any(SignUpContract.model.onFinish.class)、any(String.class)、any(String.class))。然后(SUT.onResponse(1))**
}
@试验
public void try\u sign\u success()引发异常{
成功();
ArgumentCaptor ac=ArgumentCaptor.forClass(String.class);
SUT.handleSignInButtonClick(用户名、密码);
验证(model,times(1)).trySignIn(any(SignUpContract.model.onFinish.class)、ac.capture()、ac.capture());
列表捕获=ac.getAllValues();
Assert.assertThat(captures.get(0),是(用户名));
Assert.assertThat(captures.get(1),is(PASSWORD));
验证(查看).showSignInScreen();
}
}
我将您的代码复制到一个示例中,以验证这一点。
我做了一些改动,有些只是为了我的方便。
注意,我使用JUnit5和更新的mockito版本(3.2.4
)来测试它
@injectmock
和@,它们中的任何一个都足够了
doAnswer
中使用了错误的参数。它应该是args[0]
trySignIn(侦听器、用户名、密码)
对我不起作用,因为侦听器
在您实际通过测试的类(SUT
)以及参数时引用了不同的模拟。我改为使用匹配器
编辑:
我从示例中删除了
SignUpModel
和SignUpRespository
,因为测试所做的只是模拟接口。实施与您的问题并不真正相关
listener
mock也不是必需的,因为它不再使用了。
import java.util.List;
导入org.junit.Assert;
导入org.junit.jupiter.api.beforeach;
导入org.junit.jupiter.api.Test;
导入org.junit.jupiter.api.extension.extensedWith;
导入org.mockito.ArgumentCaptor;
导入org.mockito.Mock;
导入org.mockito.mockito;
导入org.mockito.invocation.invocationMock;
导入org.mockito.junit.jupiter.MockitoExtension;
导入org.mockito.stubing.Answer;
@ExtendWith(MockitoExtension.class)
公共类SignupPresentTest{
公共接口签约合同{
界面视图{
void showSignInScreen();
void onError(整数代码、字符串消息);
}
界面模型{
接口onFinish{
无效响应(R数据);
void onError(字符串错误);
}
void trySignIn(onFinish onFinish,字符串名称,字符串密码);
}
界面演示者{
void handleSignInButtonClick(字符串用户名、字符串密码);
}
}
公共静态类SignUpPresenter实现SignUpContract.presenter、SignUpContract.model.onFinish{
SignUpContract.view视图;
签约合同模型;
公共SignUpPresenter(SignUpContract.view视图,SignUpContract.model模型){
this.view=视图;
this.model=模型;
}
@凌驾
public void handleSignInButtonClick(字符串用户名、字符串密码){
试一试{
model.trySignIn(这个,用户名,密码);
}捕获(例外e){
e、 printStackTrace();
}
}
@凌驾
公共响应(对象数据){
view.showSignInScreen();
}
@凌驾
public void onError(字符串错误){
视图。onError(1,错误);
}
}
私有静态最终字符串USERNAME=“USERNAME”;
私有静态最终字符串PASSWORD=“PASSWORD”;
@嘲弄
签约合同模型;
@嘲弄
SignUpContract.view视图;
签署人SUT;
@之前
public void setUp()引发异常{
SUT=新的SignUpPresenter(视图、模型);
}
@试验
public void try\u sign\u success()引发异常{
Mockito.doAnswer(新答案(){
@凌驾
公共对象应答(InvocationMock调用)抛出Throwable{
对象[]args=invocation.getArguments();
SignUpContract.model.onfish回调=(SignUpContract.model.onfish)参数[0];
callback.onResponse(0);
返回null;
}
}).when(model).trySignIn(Mockito.any(SignUpContract.model.onFinish.class)、Mockito.eq(用户名)、Mockito.eq(密码));
ArgumentCaptor ac=ArgumentCaptor.forClass(String.class);
SUT.handleSignInButtonClick(用户名、密码);
Mockito.verify(model,Mockito.times(1)).trySignIn(Mockito.any(SignUpContract.model.onFinish.class)、ac.capture()、ac.capture();
列表捕获=ac.getAllValues();
Assert.assertEquals(用户名,captures.get(0));
Assert.assertEquals(密码,captures.get(1));
Mockito.verify(view.showSignInScreen();
}
}
请注意,
trySignIn
调用的验证并不像您的测试那样是真正必要的