1

I created a category for NSDecimalNumber in which I take an NSString and return a NSDecimalNumber. I'm using it in a few of my view controllers and wanted to create a single global instance of NSNumberFormatter. I think this works but I have no idea on how to test it. For example, I want to NSLog every time an NSNumberFormatter instance gets allocated. How do I do that?

#import "NSDecimalNumber+amountFromTextField.h"

@implementation NSDecimalNumber (amountFromTextField)

static NSNumberFormatter *nf;

+(NSDecimalNumber *)amountFromTextField:(NSString *)amount {
    @synchronized(self) {
        if (nf == nil) {
            nf = [[NSNumberFormatter alloc] init];
        }
    }
    NSDecimal _amount = [[nf numberFromString:amount] decimalValue];
    return [NSDecimalNumber decimalNumberWithDecimal:_amount];
}

@end
Cristik
  • 30,989
  • 25
  • 91
  • 127
oky_sabeni
  • 7,672
  • 15
  • 65
  • 89

1 Answers1

4

You can extract the formatter allocation into another method, and assert on that:

+ (NSNumberFormatter*)amountFormatter;

- (void)testOnlyOneFormatterIsCreated {
    NSNumberFormatter *formatter1 = [NSDecimalNumber amountFormatter];
    NSNumberFormatter *formatter2 = [NSDecimalNumber amountFormatter];
    XCTAssertEqual(formatter1, formatter2, "Expected only one formatter to be created");
}

The problem with your current implementation is the fact you don't have access to the created formatter, thus it very hard to test it. Splitting object creation and business logic into separate units is also good for your code, as it keeps your units short and focused on one task only.

Cristik
  • 30,989
  • 25
  • 91
  • 127