Mockito/Power Mockito:在android中模拟LayoutParams的方法时无法获得预期的输出

Mockito/Power Mockito:在android中模拟LayoutParams的方法时无法获得预期的输出,android,unit-testing,mockito,powermockito,Android,Unit Testing,Mockito,Powermockito,我有一个方法: public class MarginConverter { int top = 0; int bottom = 0; int right = 0; int left = 0; public MarginConverter(String val){ top = bottom = right = left = Integer.parseInt(val); } public LayoutParams getLa

我有一个方法:

public class MarginConverter {
    int top = 0;
    int bottom = 0;
    int right = 0;
    int left = 0; 
    public MarginConverter(String val){
       top = bottom = right = left = Integer.parseInt(val);
    }

    public LayoutParams getLayoutParamsFromView(View view){
        LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
        int height, width;
        if (layoutParams == null) {
            height = LayoutParams.WRAP_CONTENT;
            width = LayoutParams.MATCH_PARENT;
            layoutParams = new LayoutParams(width, height);
            layoutParams.setMargins(left, top, right, bottom);
        } else {
            layoutParams.setMargins(left, top, right, bottom);
        }
        return layoutParams;
        }
    }
注意:变量left、top、right和bottom是构造函数调用时初始化的实例变量

我想测试一下这个方法。我模拟了view.getLayoutParams()方法。方法setMargin(int,int,int,int)并没有像前面提到的那样设置边距参数,我在测试中得到了LayoutParams(leftMargin,rightMargin,topMargin,bottomMargin)0.0的所有参数,尽管它在代码中工作正常。我应该怎么做才能得到预期的值

请帮帮我!任何帮助都将不胜感激

这是我的测试用例代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ViewGroup.LayoutParams.class})
public class MarginConverterTest {
@Mock
private View view = mock(TextView.class);

private int left = 0;
private int right = 0;
private int top = 0;
private int bottom = 0;

@Before
public void setUp() throws Exception {
    when(view.getLayoutParams()).thenReturn(null);
}

/**
 * tests output for margin conversion when one argument is given
 */
@Test
public void test_OneArgumentMarginConversion(){
    left =top = right = bottom = 5;
    MarginConverter marginConverter = new marginConverter("5");
    LayoutParams params = marginConverter.getLayoutParamsFromView(view);
    Object[] marginArray = new Object[4];
    marginArray[0] = params.leftMargin;
    marginArray[1] = params.topMargin;
    marginArray[2] = params.rightMargin;
    marginArray[3] = params.bottomMargin;
    Assert.assertArrayEquals(new Object[]{left,top,right,bottom}, marginArray);
}
}

你似乎对嘲弄的概念感到困惑。如果您模拟某个对象,这意味着它是一个伪对象(不是真实对象),并且它的所有方法调用都是假的

如果希望页边距不为零,
layoutparms(leftMargin、righmargin、topMargin、bottomMargin)
,请不要模拟
视图
设置页边距
方法

如果您的
视图
对象不是真实的(模拟、虚拟等),则您的
布局参数
也是假的(表示未知值),除非您使用模拟框架返回实际的
布局参数

简单来说,如果希望通过调用
setMargins
来设置边距,请不要模拟
setMargins
方法调用,并确保
layoutParams
不是假的

此外,在您的情况下,如果
视图
被模拟,则条件
如果(layoutParams==null)
将永远不会满足,因为
layoutParams
将是非null伪对象

解决方案-在调用时使用适当的模拟方法查看。getLayoutParams()以返回适当的real
layoutParams
对象或
null
以满足两个代码分支的要求,
if
以及
else


希望这对我有所帮助,如果我误解了你的问题,请告诉我

当我模拟视图时,视图并没有实际创建,这导致了这个问题。我使用RobolectrictTestRunner而不是PowerMockRunner,并使用shaddow应用程序上下文创建视图。成功了

现在我的测试代码是:

@RunWith(RobolectricTestRunner.class)
public class MarginConverterTest {
private int left = 0;
private int right = 0;
private int top = 0;
private int bottom = 0;
View view;
@Before
public void setUp() throws Exception {
   view = new TextView(Robolectric.getShadowApplication().getApplicationContext());
}

/**
 * tests output for margin conversion when one argument is given
 */
    @Test
    public void test_OneArgumentMarginConversion(){
    left =top = right = bottom = 5;
    MarginConverter marginConverter = new marginConverter("5");
    LayoutParams params = marginConverter.getLayoutParamsFromView(view);
    Object[] marginArray = new Object[4];
    marginArray[0] = params.leftMargin;
    marginArray[1] = params.topMargin;
    marginArray[2] = params.rightMargin;
    marginArray[3] = params.bottomMargin;
    Assert.assertArrayEquals(new Object[]{left,top,right,bottom}, marginArray);
}
}

我想检查从函数返回的LayoutParams中应用的任何边距。您的解决方案帮助我测试了这两个代码分支。但我的问题还是一样。我应该怎么做才能在调用setMargins方法时设置layoutParams中字段的值。在您的测试方法中,您正在调用
marginConverter.getLayoutParams(view)
,而您希望测试的方法是
getLayoutParamsFromView
,并且我看不到从您的测试中调用该方法。我错过什么了吗?您似乎在提供零碎的信息。我假设您的问题是希望通过执行
left=top=right=bottom=5,按照您的意愿设置实例变量
left、top、right、bottom
在测试方法中?我想你们需要展示构造函数,否则怎么会有人知道这些值的设置呢?如果通过调用在构造函数中正确设置了这些值,`MarginConverter MarginConverter=new MarginConverter(“5”);`然后,我看不出有任何理由让它们为0,如果您沿着路径,
if(layoutParams==null)
。概念很简单,如果
layoutParams
没有被模拟,方法调用
layoutParams.setMargins(左、上、右、下)
是真实的,在调用此方法之前,您需要验证这些值。那么,在调用
setMargins
之前,这些值是否非零,也就是说,在进行函数调用之前,这些值是否已正确初始化?我已通过调试代码进行了检查,在这种情况下,在进行函数调用之前,这些值是非零的,即5。我已经用全班测试(MarginConverter)和全班测试MarginConverter编辑了这篇文章