2016-05-13 113 views
4

我想验证表明public static void方法已被称为验证呼叫静态方法

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ConsoleLog.class}) 
public class AdContentDataUnitTest { 

    @Before 
    public void setUp() throws Exception { 
     PowerMockito.mockStatic(ConsoleLog.class); 
    } 

    @Test 
    public void adContentData_sendTrackingEvent_noUrl() throws Exception { 
     mAdContentData = spy(mAdContentData); 

     // PowerMockito.doNothing().when(ConsoleLog.class); 

     verifyStatic(); 
     mAdContentData.sendTrackingEvent("event1"); 
     //verifyStatic(); 
    } 
} 

sendTrackingEvent将被调用,并ConsoleLog.v(String, String)将被调用。我可以在调试,静态方法被调用时看到,但下面的日志出现,测试失败:

Wanted but not invoked com.example.logger.ConsoleLog.v(
    "AdContentData", 
    "sendTrackingEvent: event event1 does not exist." 
); 

我做过尝试,但相同的日志后添加verifyStatic,如果我删除第一个验证,没有被检查。如果我嘲笑整个ConsoleLog类,则出现错误Unfinished stubbing detected here: [...] PowerMockitoCore.doAnswer

有谁知道如何正确地做到这一点?

回答

1

有谁知道如何正确地做到这一点?

是的。不要这样做。

比方说,你有一个调用静态方法是这样一类:

class Person { 
    private final int id; 

    Person() { 
     id = IdGenerator.gen(); 
    } 
} 

提取静态调用非静态方法:

class Person { 
    private final int id; 

    Person() { 
     id = generateId(); 
    } 

    protected int generateId() { 
     return IdGenerator.gen(); 
    } 
} 

现在你可以写一个测试,覆盖提取的方法:

final int id = 1; 
    Person person = new Person() { 
     @Override 
     protected int generateId() { 
      return id; 
     } 
    }; 

    // test with person, knowing we control id 

但理想的解决方案实际上是将被测代码重构为n根本不使用这种静态调用,而是依赖注入。

+0

这是一个解决方案,但它降低了性能,因为我们需要更多地调用一个方法(我在Android和性能方面) –

+0

编译器可能很好地内联这样的方法调用。你确定它有明显的性能差异吗?你测过它了吗?我忘了提到理想的解决方案是重构代码在测试中不使用静态调用,但使用依赖注入 – janos

+0

好吧,'ConsoleLog'是一个包装类的http://developer.android.com/reference/android/util /Log.html –