如何对WCF服务进行单元测试?

18

我们有许多DLL文件,可以访问我们的数据库和其他应用程序和服务。

我们使用薄的WCF服务层来封装这些DLL,并由客户端进行消费。

我不太确定如何编写仅测试WCF服务层的单元测试。我是否应该只为DLL编写单元测试,为WCF服务编写集成测试?如果我的单元测试实际上要连接到数据库,则它们将不会是真正的单元测试。我也知道在单元测试中不必测试WCF服务主机。

因此,我对要测试的内容及方式感到困惑。


1
没有必要对WCF服务进行单元测试,编写集成测试是完全可以的。 - Michael Freidgeim
避免使用模拟对象,一个单元不是没有任何外部依赖的类。一个单元是端到端的业务逻辑切片,即使它涉及数据库。您可以始终使用内存中的数据库,甚至更好地使用嵌入式数据库,例如BerkeleyDB进行测试。您不需要实际的数据库驻留在其他机器上。这样,您可以有效地测试您的单元,而无需大量模拟。 - Narendra Pathai
3个回答

7
如果你想对WCF服务类进行单元测试,请确保在设计时考虑松耦合,这样你就可以模拟每个依赖项,以便仅测试服务类本身内部的逻辑。
例如,在下面的服务中,我使用“贫人依赖注入”来分离我的数据访问存储库。
Public Class ProductService
    Implements IProductService

    Private mRepository As IProductRepository

    Public Sub New()
        mRepository = New ProductRepository()
    End Sub

    Public Sub New(ByVal repository As IProductRepository)
        mRepository = repository
    End Sub

    Public Function GetProducts() As System.Collections.Generic.List(Of Product) Implements IProductService.GetProducts
        Return mRepository.GetProducts()
    End Function
End Class

在客户端,您可以使用服务契约的接口来模拟 WCF 服务本身。
<TestMethod()> _
Public Sub ShouldPopulateProductsListOnViewLoadWhenPostBackIsFalse()
    mMockery = New MockRepository()
    mView = DirectCast(mMockery.Stub(Of IProductView)(), IProductView)
    mProductService = DirectCast(mMockery.DynamicMock(Of IProductService)(), IProductService)
    mPresenter = New ProductPresenter(mView, mProductService)
    Dim ProductList As New List(Of Product)()
    ProductList.Add(New Product)
    Using mMockery.Record()
        SetupResult.For(mView.PageIsPostBack).Return(False).Repeat.Once()
        Expect.Call(mProductService.GetProducts()).Return(ProductList).Repeat.Once()
    End Using
    Using mMockery.Playback()
        mPresenter.OnViewLoad()
    End Using
    'Verify that we hit the service dependency during the method when postback is false
    Assert.AreEqual(1, mView.Products.Count)
    mMockery.VerifyAll()
End Sub

在没有多个实现的情况下使用接口需要额外的努力来保持一切同步。此外,它还隐藏了您实际上提供多个实现的情况。请参见http://stackoverflow.com/questions/90851/is-creating-interfacesfor-almost-every-class-justified-or-are-interfaces-overus中的更多示例。 - Michael Freidgeim

7
取决于这个轻量级的WCF服务所做的事情。如果它真的很轻,而且没有有趣的代码,那就不要费心单元测试了。如果没有真正的代码,不要害怕不进行单元测试。如果测试不能比测试下的代码至少简单一级,那就不要费心。如果代码很蠢,测试也会很蠢。你不想维护更多的愚蠢代码。
如果你可以进行一直到数据库的测试,那太好了!这甚至更好。这不是一个“真正的单元测试”?完全没有问题。

4

你的服务的消费者并不关心服务下面的内容。 为了真正测试你的服务层,我认为你的层需要深入到DLL和数据库中,并编写至少CRUD测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接