gpt4 book ai didi

ios - 在单元测试中,将模拟值设置为参数(按引用传递)

转载 作者:行者123 更新时间:2023-12-02 07:38:28 25 4
gpt4 key购买 nike

我有一个方法:

-(void)startTaskForResult:(long long*)result {
...
}

我想要对上面的函数进行单元测试调用的函数:

-(void)doWork {
long long result = 0;
[self startTaskForResult:&result];
}

我正在使用OCMock库进行单元测试。在我的测试用例中,我想将 result 参数设置为模拟值,例如100 无需关心 -(void)startTaskForResult:(long long*)result 的实际实现。

我尝试了以下方法:

-(void)testDoWork{
// try to set 100 to argument 'result'
OCMStub([classToTest startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]);
// run the function, but it doesn't use mocked value 100 for argument 'result'
[classToTest doWork];
...
}

但是,当我运行测试时,它不会使用模拟值 100 作为参数结果。那么在我的例子中,将模拟值设置为参数的正确方法是什么?

最佳答案

回答你的问题有几点:

您的问题的代码:

- (void)testDoWork 
{
id mock = OCMPartialMock(classToTest)
OCMStub([mock startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]).andForwardToRealObject;
// set your expectation here
[classToTest doWork];
}
  1. 解决您的特定问题:

    • 您的对象应该是部分模拟的
    • 你的方法应该被 stub (你做到了)
    • 您的 stub 应该转发到真实对象(我假设您需要调用方法 startTaskForResult: 实现)
  2. 但是,您会遇到问题,因为您使用了错误的测试方法;

有 3 种最常见的编写单元测试的策略:

  1. Arrange-Act-Assert 用于测试方法
  2. Given-When-Then 用于测试函数
  3. Setup-Record-Verify 用于测试副作用。这通常需要模拟。

所以:

  • 如果您想测试 startTaskForResult: 返回特定值 - 您应该只调用该值并期望返回值(不是您的情况,方法返回类型为 void)
  • 如果方法更改了对象的状态 - 您应该预期状态会发生变化,例如属性值等
  • 如果调用 doWork 会产生调用 startTaskForResult: 的副作用,您应该 stub 它并期望它的调用,就像我在上面的代码中编写的那样。然而(!!!),但是你不应该期待这样的事情。这不是一种有多大测试意义的行为,因为它是内部类实现细节。一种可能的情况是,当两种方法都是公共(public)的并且在类契约中明确说明时,一种方法应该通过一些初步设置来调用另一种方法。在这种情况下,您期望使用一些状态/参数进行方法调用。

为了让您的应用程序代码可测试,您需要不断重构您的代码。有些代码是不可测试的,最好采用应用程序代码,而不是尝试用测试来覆盖它。你失去了测试的最初目标 - 重构安全性和低成本的更改。

关于ios - 在单元测试中,将模拟值设置为参数(按引用传递),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39152107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com