开发者

Objective C - Unit Testing & Mocking Objects?

开发者 https://www.devze.com 2023-02-20 19:18 出处:网络
How do you unit test Objective C code? (iPhone) In other languages such as java and .Net you can use Dependency Injection, to be able to unit test and pass mocked object in your current code.

How do you unit test Objective C code? (iPhone)

In other languages such as java and .Net you can use Dependency Injection, to be able to unit test and pass mocked object in your current code. However, I could not find a reliable dependency injection framework for objective c.

Let's say you want to wr开发者_运维百科ite a unit test for the code below, how can you mock MyObject?

- (void) methodToBeTested
{
     NSString str = @"myString";
     MyObject object = [[MyObject alloc] init];
     [object setString:str];
     [object doStuff];
     [object release];
}

This is how I would do it with dependency injection. Is there a similar way to achieve this on objective c?

@Inject MyObject object;

public void methodToBeTested()
{
     String str = "myString";
     // object is automatically instantiated (Dependency Injection)
     object.setString(str);
     object.doStuff();
}


Inversion of control is still feasible in objective-c. You can certainly design your classes with constructor-based or property-based dependency injection in mind but I don't think you'll find an annotation based dependency injection framework like you are used to.

[[ClassToBeTested alloc] initWithDependency:foo andOtherDepedency:bar];

ClassToBeTested *objectUnderTest = [[ClassToBeTested alloc] init];
objectUnderTest.dependency = foo;
objectUnderTest.otherDependency = bar;

I've seen a couple of different approaches to building dependency injection frameworks for objective-c including https://github.com/mivasi/Objective-IOC but I can't comment on their maturity or usefulness.

For object mocking and stubbing look at OCMock.


how can you mock MyObject?

- (void) methodToBeTestedWithObject:(MyObject *)object
{
     NSString str = @"myString";
     [object setString:str];
     [object doStuff];
}

To test:

- (void)testMethodToBeTested {
    id mockMyObject = [OCMock mockForClass:[MyObject class]];

    [[mockMyObject expect] setString:[OCMock any]];
    [[mockMyObject expect] doStuff];

    [objectToTest methodToBeTestedWithObject:mockMyObject];
    [mockMyObject verify];
}

Using, as mentioned in @Jonah's answer, the excellent OCMock. Don't bother trying to do capital-D, capital-I Dependency Injection in obj-c, it's more work than it's worth.


Here's a dependency injection framework for Objective-C: http://www.typhoonframework.org

Besides addressing on the design aspects of DI, it has a strong focus on being able to configure components for production vs test scenarios (integration testing). This includes:

  • Ability to inject values represented as strings - these are converted to the required type at runtime.
  • Configuration management via an external properties file.
  • Asynchronous test execution - allowing you to test methods that run on a background thread.
0

精彩评论

暂无评论...
验证码 换一张
取 消