当你想在测试中模拟一个繁重的方法时,如何在scala中设计类?

时间:2014-04-01 15:36:27

标签: scala unit-testing mockito traits

我有一个名为HtmlConverter的类,它可以将html页面转换为纯文本文件,并且可以从URL中检索html内容。

我想对它进行单元测试,所以我想模仿"从url"中检索html的部分。部分。现在我有两个选择:

1。定义对象HtmlRetriever并在HtmlConverter

中使用它

代码:

class HtmlRetriever {
    def getContentFromUrl(url:String) = { 
        // heavy work
    }
}

class HtmlConverter {
    val retriever = new HtmlRetriever
    def convertFromUrl(url:String) = {
         val content = retriever.getContentFromUrl(url)
         // convert
    }
}

测试时,请使用mockitospec2

object MyHtmlConverter extends HtmlConverter {
    override val retriever = mock[HtmlRetriever]
}

MyHtmlConverter.retriever.getContentFromUrl(...) returns "<html>...</html>"

val pdf = MyHtmlConterter.convertFromUrl(...)

// assert the invocation
there was one(MyHtmlConverter.retriever).getContentFromUrl(...)

这有效,但我不确定它是否是最佳解决方案

2。使用特质

现在我想尝试一下特质

trait HtmlRetriever {
    def getContentFromUrl(url:String) = { 
        // heavy work
    }
}

class HtmlConverter extends HtmlRetriever {
    def convertFromUrl(url:String) = {
         val content = getContentFromUrl(url)
         // convert
    }
}

测试时,我无法找到使用mockito的方法,我可以使用自定义覆盖方法:

object MyHtmlConverter extends HtmlConverter {
    override def getContentFromUrl(url:String) = "<html>from test</html"
}

然后使用新的MyHtmlConverter方法测试对象getContentFromUrl

通过这种方式,我无法使用mockito,因此我无法验证调用,如:

there was one(htmlRetriever).getContentFromUrl(...)

我不满意

是否有最佳做法可以使用mockito或其他内容在scala中执行此类测试。

2 个答案:

答案 0 :(得分:0)

您可以创建一个类的声明,扩展测试中的特征,然后模拟该类:

class TestHtmlConverter extends HtmlConverter

/* other code elided */
val htmlConverter = mock[TestHtmlConverter]
htmlConverter.getContentFromUrl(/* ... */) returns "<html />"

答案 1 :(得分:0)

您可以采用不同的方式构建方法,以避免需要模拟。

class HtmlConverter {
    val retriever = new HtmlRetriever
    def convertFromUrl(url:String) = {
         val content = retriever.getContentFromUrl(url)
         convert(content)
    }
    def convert(content: ContentFromUrl) = {
        // convert
    }
}

然后您可以直接测试convert。一套不同的测试可以涵盖retriever,您的convertFromUrl方法现在非常简单,不需要直接的单元测试。