2012-11-02 7 views
7

나는 현재 다음 테스트 코드가 있습니다IO가 아닌 모나드에서 HUnit을 테스트 프레임 워크와 함께 사용할 수 있습니까?

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 = ... 

이 좀 작동을하지만 지저분한입니다. 나는 오히려 테스트중인 다양한 것들을 반환하지 않고 무언가를 쓸 수있게되었고, 대신 그들이 이해할 수있는 주장을했다.

나는 Assertable 클래스가 있음을 알았지 만, 나는 아마 많은 것들을 재발 명해야 할 것 같다.

+0

큰 질문입니다. 처음 사용했을 때 그 유형에 IO가 필요한 이유가 궁금합니다. –

+0

모나드가 'liftIO'를 지원합니까? – hammar

+0

@hammar 그렇습니다. 그리고 내가해야 할 일은 'liftIO'로 테스트를 수행하는 것만 큼은 알 수 없습니다. 그러나, 질문을 열어두고 다른 방법이있을 수 있습니다. – ocharles

답변

1

모나드가 IO a 유형의 IO 계산을 반환하지 않는 이유는 무엇입니까? 순수한 값입니까?

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 

보너스가 하나 모나드에 의해 시험의 컬렉션을 반환 할 수 있다는 것입니다 : 같은 의견, 모나드가 MonadIO의 인스턴스 사소한 인 경우 이후 는 는 모나드 순수 계산을 할 수 있다고 가정 계산, 그냥 목록에 모나드와 마찬가지.

+0

모든 어설 션이 어설 션에 의존하는 코드보다 훨씬 늦기 때문에 저는이 코드를 정말 좋아하지 않습니다. 어설 션이 성립되지 않아 코드 자체가 이미 예외를 발생 시켰기 때문에 어설 션이 실제로 실패하지 않음을 의미합니다. – ocharles

+0

내 예제에서'test1'과'test2' 사이의 코드가 그 테스트에 의해 던져진 예외를 잡아야한다는 것을 의미합니까? 그런 경우, 속임수를 쓰지 않는 한 (즉'안전하지 않은'을 사용하는) 모나드는 MonadIO의 인스턴스 여야합니다. 하스켈의 순수 코드가 예외를 잡을 수 없기 때문입니다. 당신이 말했듯이,이 사건은 'liftIO'로 해결하기가 쉽지 않습니다. 혹시 하스켈이 _ 게으른 언어라는 사실을 잊고 있습니까? 게으른 언어의 임무는 평가 순서가 중요하지 않음을 보장하는 것입니다 (IO 문제 제외). "liftIO"나 솔루션이 작동하지 않는 예제를보고 싶습니다. – mnish