我有一个方法如下
public class ClientClass {
public void clientMethod() {
while(true){
doSomethings.....
}
}
}
我正在尝试使用mockito进行测试。我可以调用clientMethod,但是因为在clientMethod中有一段时间(true),所以调用永远不会返回,我永远不会到达我的assert语句(当然)在clientMethod()调用之后发生。 有没有办法在从我的测试用例中循环迭代后停止循环?
答案 0 :(得分:2)
技术上你不能在测试中打破无限循环而不从其中抛出异常。如果循环中有东西可以模拟,那么它可能会为你产生异常。
当你发现自己遇到这样的情况时,如果需要进行笨拙的测试工作,那么就该停下来思考一下设计了。不可测试的代码通常是不易维护的,并且不是很容易理解。所以我的建议是摆脱无限循环并引入适当的循环条件。毕竟,没有任何应用程序会永远存在。
如果您仍然相信无限循环是最好的方法,那么您可以执行轻微的分解以使事情更具可测性:
public class ClientClass {
// call me in production code
public void clientMethod() {
while(true){
doSomethings();
}
}
// call me in tests
void doSomethings(){
// loop logic
}
}
答案 1 :(得分:0)
这对我来说有点沮丧......因为我喜欢用控制台处理程序启动最复杂的GUI应用程序。
我在这里使用的语言是Groovy,它是Java的一种奇妙的扩展,可以与普通的旧Java混合使用。
class ConsoleHandler {
def loopCount = 0
def maxLoopCount = 100000
void loop() {
while( ! endConditionMet() ){
// ... do something
}
}
boolean endConditionMet() {
loopCount++
loopCount > maxLoopCount // NB no "return" needed!
}
static void main( args ) {
new ConsoleHandler().loop()
}
}
...在测试类(也在Groovy中),然后你可以去
import org.junit.contrib.java.lang.system.SystemOutRule
import org.junit.contrib.java.lang.system.
TextFromStandardInputStream.emptyStandardInputStream
import static org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import static org.mockito.Mockito.*
class XXTests {
@Rule
public SystemOutRule systemOutRule = new SystemOutRule().enableLog()
@Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream()
ConsoleHandler spyConsoleHandler = spy(new ConsoleHandler())
@Test
void readInShouldFollowedByAnother() {
spyConsoleHandler.setMaxLoopCount 10
systemInMock.provideLines( 'blah', 'boggle')
spyConsoleHandler.loop()
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'blah' )
assertThat( systemOutRule.getLog() ).containsIgnoringCase( 'boggle' )
这里发生的美妙事情是,只需声明maxLoopCount
该语言会自动创建两种方法:getMaxLoopCount
和setMaxLoopCount
(您甚至不必费心使用括号)
当然下一个测试是“如果用户输入Q就必须退出循环”或者其他什么......但关于TDD的一点是你最初想要失败!
如果您必须使用普通的旧Java,可以复制以上内容:当然,您必须创建自己的setXXX
方法。
答案 2 :(得分:0)
我陷入困境是因为我错误地从方法内部调用了相同的方法。
public OrderEntity createNewOrder(NewDepositRequest request, String userId) {
return createNewOrder(request, userId);
}