2014-01-17 86 views
0

在我的單元測試中,我有一個具有多個外鍵的模型的工廠函數。我希望該工廠函數是可變參數,允許用戶指定要用作外鍵的對象作爲關鍵字參數,但調用相關的工廠函數爲任何遺漏的產生一個新的函數。使用函數值作爲kwargs.get()默認

我原來寫的東西,如:

def model_factory(i, **kwargs): 
    """Create a new Model for testing""" 
    test_model_data = { 
     'fk1': kwargs.get('fk1', fk1_factory(i)), 
     'fk2': kwargs.get('fk2', fk2_factory(i)), 
     'fk3': kwargs.get('fk3', fk3_factory(i)), 
    } 
    return Model.objects.create(**test_model_data) 

但即使關鍵字存在,造成了很多的副作用,與我的測試干擾這個調用fkN_factory()方法。我的問題是,是否有一個更簡單的方法做什麼,我打算在這裏沒有導致大量不必要的函數調用,而不是我現在有,這更像是:

def model_factory(i, **kwargs): 
    """Create a new Model for testing""" 
    test_model_data = { 
     'fk1': kwargs.get('fk1', None), 
     'fk2': kwargs.get('fk2', None), 
    } 
    if kwargs['f1'] is None: 
     kwargs['f1'] = fk1_factory(i) 
    if kwargs['f2'] is None: 
     kwargs['f2'] = fk2_factory(i) 

回答

2

你要分解出以某種方式重複代碼。最簡單的是:

def get_value(mapping, key, default_func, *args): 
    try: 
     return mapping[key] 
    except KeyError: 
     return default_func(*args) 

# ... 

test_model_data = { 
    'fk1': get_value(kwargs, 'fk1', fk1_factory, i), 
    'fk2': get_value(kwargs, 'fk2', fk2_factory, i), 
    # etc. 
} 

幾乎就像你原來的非工作版本一樣簡單。

你甚至更遠藉此:

def map_data(mapping, key_factory_map, *args): 
    return {key: get_value(mapping, key, factory, *args) 
      for key, factory in key_factory_map.items()} 

# … 

test_model_data = map_data(kwargs, { 
    'fk1': fk1_factory, 
    'fk2': fk2_factory, 
    # … 

    }, i) 

但我不知道這其實更好。 (如果你有一個明顯的位置來定義從外部到key-to-factory的映射,那很可能是;如果沒有,可能不會)

+0

這是一個非常不錯的重構。謝謝! –

相關問題