dugla
dugla

Reputation: 12954

OCMock. Why does the second of these test pass?

I am getting up to speed of mock-ing with iOS using OCMock. I wrote a simple mock-ing unit test that passes when - based on the expectation I set - it should fail.

Here is the code:

// Scientific Calculator class
@implementation ScientificCalculator

- (NSNumber *)sqrt:(NSNumber *)input {
    return [NSNumber numberWithDouble:sqrt([input doubleValue])];
}

@end

// unit test
-(void) testScientificCalculatorSqrt {

    NSNumber *input = [NSNumber numberWithDouble:4];
    ScientificCalculator *scientificCalculator = [[ScientificCalculator alloc] init];

    NSNumber *expected = [NSNumber numberWithDouble:2];

    NSNumber *result = [scientificCalculator sqrt:input];

    STAssertEquals([result doubleValue], [expected doubleValue], nil);

}

// unit test
-(void)testScientificCalculatorMocking {

    // setup
    NSNumber *input = [NSNumber numberWithDouble:44];
    id scientificCalculator = [OCMockObject mockForClass:[ScientificCalculator class]];

    // expect
    NSNumber *expected = [NSNumber numberWithDouble:2];
    [[[scientificCalculator expect] andReturn:expected] sqrt:input];

    // test
    NSNumber *result = [scientificCalculator sqrt:input];

    // verify
    STAssertEquals([result doubleValue], [expected doubleValue], nil);

    [scientificCalculator verify];
}

The testScientificCalculatorMocking unit test uses 44 as input to sqrt. I set the expected values to 2. Both STAssertEquals and [scientificCalculator verify] pass successfully.

Can someone please explain what I am doing wrong here?

Thanks,
Doug

Upvotes: 0

Views: 177

Answers (2)

Christopher Pickslay
Christopher Pickslay

Reputation: 17772

Your first test is the correct way to test something like this. There's no reason to mock your calculator, because its behavior is what you're testing.

Generally you mock things that are orthogonal to what you're testing and may have side effects if you execute them in your test. For example, say you had a method that calculated the square root of Apple's stock price. You might mock the web service call to retrieve the stock price, so your test doesn't make network calls and the price is static in your test. Then you'd pass the pre-defined price to your calculator and verify that the square root value it gives you is correct.

As to stub vs. expect, expect means this method must be called once. stub means it may or may not be called, any number of times. In both cases, the andReturn part just defines what will be returned when the method is invoked on your mock. Remember, a mock is dumb, so you need to tell it what to return.

Upvotes: 1

trydis
trydis

Reputation: 3925

You've told the mock to return 2 (expected) when sqrt is called with 44 (input). The result variable will therefore contain the value 2. You're then comparing result (2) and expected (2), which will pass.

Upvotes: 1

Related Questions