2012-11-02 13 views
7

Şu anda aşağıdaki test kodu vardır:HUnit'i IO'dan başka bir monadde test çerçevesiyle kullanmak mümkün mü?

testUpdate :: Test 
testUpdate = testCase "update does change artist" $ do 
    (created, Just revised, parents) <- mbTest $ do 
    Just editor <- fmap entityRef <$> findEditorByName "acid2" 

    created <- create editor startWith 
    let artistId = coreMbid created 

    newRev <- update editor (coreRevision created) expected 

    editId <- openEdit 
    includeRevision editId newRev 
    apply editId 

    found <- findLatest artistId 
    parents <- revisionParents newRev 

    return (created, found, parents) 

    coreData revised @?= expected 

    assertBool "The old revision is a direct parent of the new revision" $ 
    parents == [coreRevision created] 

    where 
    startWith = ... 
    expected = ... 

Bu tür çalışır, ancak dağınık. Test altındaki çeşitli şeyleri geri göndermeye gerek kalmadan bir şeyler yazmayı ve bunun yerine anlamlı olduklarını iddia ettim.

Assertable sınıfının olduğunu görüyorum, ama sanırım muhtemelen bir sürü şeyi yeniden icat etmek zorundayım.

+0

Harika bir soru, ilk kullandığımda neden her şeyin IO'ya ihtiyaç duyduğunu merak ettiğimi hatırlıyorum. –

+0

Monad 'liftIO'yu destekliyor mu? – hammar

+0

@hammar Yaptığım her şeyin, "liftIO" ile yapılan testlerin kaldırılması olduğu gerçeğini kaçırdığımdan emin değilim. Bununla birlikte, soruyu açık bırakacağım, belki başka yollar da olabilir :) – ocharles

cevap

1

Neden yalnızca sizin monad'ınız IO a türünde bir IO hesaplaması döndürüyor, bu değeri nedir?

newtype M a = M {runM :: ....} 
instance Monad M where 
    ... 

makeTest :: M Assertion 
makeTest = do 
    created <- .. 
    found <- .. 
    parents <- .. 
    let test1 = coreData revised @?= expected 
    ... 
    let test2 = assertBool "The old revision..." $ 
        parents == [coreRevision create] 

    return $ test1 >> test2 

testUpdate :: Test 
testUpdate = testCase "update does change artist" $ runM makeTest 

Bonus tek monadic tarafından testlerin bir koleksiyon geri dönebilirler şudur: olarak Yorumunuza, monad MonadIO örneğidir önemsiz olduğu durumda bu yana , monad saf hesaplama izin verdiğini varsayalım hesaplama, sadece liste monadında olduğu gibi.

+0

Gerçekten bunu sevmiyorum çünkü tüm iddialar, iddiaya bağlı olan koddan daha geç çalışır. Bu muhtemelen, iddiaların gerçekten başarısız olmayacağı anlamına gelecektir, çünkü kodun kendisi, iddiaların beklemediği için zaten bir istisna atmış olabilir. – ocharles

+0

Örnekte 'test1' ve' test2' arasındaki kodun bu testler tarafından atılan bir istisna yakalaması gerektiği anlamına mı geliyor? Ancak, bu durumda, sizin monad, hile yapmıyorsanız (yani 'güvensiz *' kullanarak) Haskell saf kodunda bir istisna yakalanamazsa MonadIO'nun bir örneği olmalıdır. Dediğiniz gibi, bu durum 'liftIO' ile çözmek için önemsiz. Belki de Haskell'in bir _lazy_ dili olduğunu unuttunuz mu? Tembel bir dilin görevi, değerlendirme sırasının önemli olmamasını sağlamaktır (IO olayı hariç). Ne 'liftIO' ne de benim çözümümün işe yaramadığı bir örnek görmek isterim. – mnish

İlgili konular