2015-05-25 13 views
2

我有兩個需要模塊:的最佳方式,使得它的狀態是很容易嘲笑和測試

state.js

define(function() { 
    var stateObj = {hello:"test!"}; 

    return { 
     getObj: function() { 
      return stateObj; 
     } 
    }; 
}); 

main.js

define(['state'],function (global) { 
    var privateFn = global.getObj() 

    return { 
     getHello: function() { 
      if(privateFn.hello == "test!") 
       //do someoperation 
     }, 
     changeState : function() { 
      //changes the privateFn state 
     } 
    }; 
}); 

state模塊將該對象提供給main模塊,該模塊用於實習al狀態存儲。爲main的內部狀態保留獨立模塊的原因是爲了便於測試,因此在我的測試案例中,我可以注入假冒的state模塊並檢查main模塊的工作方式。

由於我是js世界的新手,我在這裏採取的方法是否正確,我不確定。

+0

爲什麼近距離投票? – batman

回答

1

如果您得到一個downvote,那很可能是因爲它很難以明確的方式回答。事實上,我正在查看代碼,甚至不知道你在問什麼。以下是我的一些想法,但請注意其他人可能會非常不同意。

你的狀態是一個單身人士,所以它應該很容易測試。比方說,你上面的changeState方法是這樣的:

changeState: function (key, value) { 
    privateFn[key] = value; 
} 

然後你就可以既包括statemain測試它,然後調用main.changeState,看看state更新預期:

main.changeState('foo', 'bar'); 
expect(state.foo).toBe('bar'); 

其他如何做到這一點(如果state不是一個單身人士),實際上是暴露您的main狀態。這通常是通過在下劃線前面加上下劃線來實現的,所以它被認爲是私有的(命名約定,它實際上並不是私有的)。然後,在你的測試中,你可以「欺騙」並直視狀態。

main.changeState('foo', 'bar'); 
expect(main._state.foo).toBe('bar'); 

另一種方式,是通過依賴注入(這是在角度世界流行)。這意味着main需要成爲某種工廠或某個類。如果從Java世界的時候,再一類可能是最有意義的:

// Some other file where both main.js and state.js is imported 
var main = new Main({ 
    state: state 
}); 

所以main.js不會導入自身的東西。

我希望這能回答你的問題。當我在(打字)時:小心你的命名。 global通常指的是window(所以root),所以有global指的是你的狀態很混亂。給它同名:state。你的privateFn也是一個對象,而不是一個函數(因爲後綴將暗示Fn)。也令人困惑。

第三件事,我不確定每個人都會同意我的看法,那就是「國家」應該指的是國家本身。它在這裏是一個包裝。有點像來自BackboneJS的Model(其中attributes就是我所說的state)。這兩者之間的區別是很重要的:

  1. 的包裝,露出有用的方法和其他的東西
  2. 和實際數據(通常是一個對象)。

實際數據通常可以(如果不是總是)轉換成JSON併發送存儲在服務器上。與Java(我認爲?)不同,你的狀態在任何時候都應該很容易從它的類/包裝器中分離出來。包裝器可以(應該)依賴於數據,但數據絕對不應該依賴於它的包裝器。


編輯

這只是我恍然大悟,也許你的意思爲main.js是數據的封裝器(和唯一的包裝)。如果是這樣的話,那麼我會以不同的方式構建它。我只有一個文件。喜歡的東西:

function modelFactory (options) { 
    var state = options.state || {}; 

    // Useful methods... 
    return { 
     get: function (key) { 
      return state[key]; 
     }, 
     set: function (key, value) { 
      state[key] = value; 
      // Maybe trigger some change event for others to listen for 
     }, 
     toJSON: function() { 
      return JSON.stringify(state); 
     } 
     // ... 
    } 
} 

然後進行測試,你可以做

var model = modelFactory({ 
    state: {foo: 'bar'} 
}); 

expect(model.get('foo')).toBe('bar'); 

model.set('hello', 'world'); 
expect(model.get('hello')).toBe('world'); 

上述我,是Backbone.Model的基礎。

+0

這個問題根本不是downvoted。 –

+0

這只是他對自己對答案的評論。 :-) –