2017-08-25 123 views
1

您能否介绍一下mockito方法验证的任务?文档说,这个方法检查方法是否被调用。但是,如果它真的有用,你能举个例子吗?通常在测试方法中,我们调用一个方法,然后检查,我们现在调用它了吗?听起来怪怪的。Mockito,方法验证任务

+0

只是为了记录:有时候新手会忘记接受答案。所以 - 考虑在某个时候接受其中一个答案;-) – GhostCat

+0

我不会忘记......我不知道正确的答案)))所以,我不能在将来desinform某人 –

+0

你消化输入,然后你考虑哪些让你理解了这个问题。你有很好的投入,不应该从那里挑选一些东西。 – GhostCat

回答

1

为了简化...假设您正在测试方法A与某些参数。什么方法A做的是调用方法B,CD

With Mockito.verify您可以测试方法B,C,D真的被调用。这甚至让你可以指定更复杂的测试,如:

  • ATLEAST(1)
  • atMost(10)

方法时您正在测试的行为真的可以有用根据您调用的参数有所不同。

+0

我没有正确理解你, 我有方法: public void method1(){ method2(); () } public void method2方法1(); verify(mResource).method2(); - 我得到绿色测试线?但我有红色。它说我: 通缉但未调用: mResource.method2(); 我在做什么错误的方式? –

2

这种类型的检查通常只是为了确保使用指定参数使用特定对象。假设您正在测试执行某些操作的业务服务,并且在此过程中还将某种审计线索存储在数据库中。

在数据库中存储这种信息已经在其他地方(单独的单元测试或某种外部库被使用)测试过,因此您不需要检查审计数据是否正确存储。为了你的测试用例,这个方法被调用的信息就足够了。这就是'验证'方法的用例。

2

通常在测试方法中,我们调用一个方法,然后...检查,我们现在调用它了吗?听起来怪怪的。

您不验证您是否调用了测试方法。你验证了无论测试结果如何,都调用了一些依赖项(你已经用模拟代替了)。

因此,例如,在测试密码检查器方法时,您想断言除了拒绝不正确的密码外,还会调用一些审计后端系统来注册失败的登录尝试。您的模拟对象将代表该后端系统,您可以使用它来验证它最终被调用(还有适当的参数)。

3

它是这样的:

public class UnderTest { 
    private Foo foo; 

    public UnderTest(Foo foo) { this.foo = foo }; 

    public void bar() { foo.foo(); } 
} 

现在假设您提供嘲笑 foo的实例UnderTest。并且你想要当然foo.foo()被调用bar()被调用时。

然后您使用verify()确保发生预期呼叫。

换句话说:测试需要验证方法的行为。理想情况下,他们通过对由测试方法返回的值声明做到这一点。但并非所有的方法都会返回一些东然后你可能验证你的代码至少检查某些期望的调用所拥有/传递给被测试的类的对象确实发生过。然后你需要verify()

0

让我们假设你有一些DAO类,它通过普通的JDBC与数据库交互。您有一些方法可以在数据库中写入数据,并希望对其进行单元测试。要这样做,你可能会模仿Connection类。在写入数据库时​​,您可能会在此模拟上调用commit方法,但返回类型为void,因此您无法保证在测试期间调用该方法。要解决这些问题,您可以使用verify。 希望它有帮助!

+0

是否表示验证检查成功\t 完成方法? –

+0

@MariaKarpikova,它只是检查该方法被调用。 –

0

方法返回东西或void
在单元测试中,作为一个方法返回的东西,通常你想用特定的值来模拟它的结果,并检查被测方法的流程是否继续。
它是有道理的,仿佛一个模拟方法返回的东西,通常你需要它的结果:无论是在测试方法的下一个语句或由被测试的方法返回的结果。

由于方法什么也没有返回(void),事情是不一样的:你不能嘲笑它的结果。
但是你可以断言这个方法是被调用的并且具有预期的参数。

例如想象一个PrinterService类打印文档

public class PrintService{ 
... 
    public void printMessage(String message){ 
    os.print(message); 
    } 
} 

而且假设你需要另一个类的单元测试时将其隔离。
下面的方法进行测试:

public class PrintClient{ 
... 
    PrintService printService; 

    public void print(String message, PrinterParameters printerParameters...){ 
    ... // do some tasks 
    ... 
    printService.print(message); 
    ...   
    } 
} 

PrintService.print()回报什么。
因此,在PrintClient的单元测试中,您不想模拟PrintService.print()的结果,因为它没有。
您只需检查是否使用传递给 的message参数调用PrintClient经过测试的方法。

@RunWith(MockitoJUnitRunner.class) 
public class PrintClientTest{ 

    @Mock 
    PrintService printServiceMock; 
    ... 
    @Test 
    pubic void print(){ 
     ... 
     String message = "my message"; 
     PrintClient printClient = new PrintClient(printServiceMock); 
     printClient.print(message, ...); 
     // 
     Mockito.verify(printServiceMock).print(message); 
     ... 
    } 
} 
+0

@Thilo真的很抱歉,但我不确定你的意思。我不想在模拟对象上调用方法,因为我只想验证服务是通过我单元测试的客户端提供的良好参数调用的。 – davidxxx

+0

啊,我的坏,抱歉,在那里失踪@InjectMocks感到困惑。 –

+1

@Florian Schaetz不,这是我。我认为我可能不好选择了命名。 'PrintClient.print()'和'PrintService.print()'可能会让人困惑。我添加了一个明确的构造函数来更清晰。 – davidxxx