【问题标题】:Unit Testing Methods that make WCF Service Call?进行 WCF 服务调用的单元测试方法?
【发布时间】:2015-03-06 12:29:04
【问题描述】:

第一次尝试任何真正的单元测试。我有一个 WPF 客户端应用程序,它从 WCF 服务中的方法接收数据。这些方法调用是直接从客户端应用程序中的视图模型进行的:

   public string LoadArticle()
    {
       MyServiceClient msc = new MyServiceClient();
       return Article = msc.GetArticle(_UserName);
    }

然后我有一个测试项目,我在其中新建了一个视图模型,然后调用我的方法:

    [TestMethod]
    public void LoadArticleTestValid()
    {
        var articleViewModel = new ArticleViewModel("Thomas");

        string userName = "Thomas";
        string expected = "Article 1";

        var actual = articleViewModel.LoadArticle(userName); 

        etc.           
    }

显然这个测试会失败,因为客户端应用程序无法访问服务来调用LoadArticle。这种情况如何解决?我是使用依赖注入并将某种类型的 IMyService 接口传递给构造函数,而不是在 ViewModel 中创建 MyServiceClient 还是以某种方式模拟服务?

【问题讨论】:

标签: c# wpf wcf unit-testing automated-tests


【解决方案1】:

这就是问题所在:

MyServiceClient msc = new MyServiceClient();

这会在ArticleViewModelMyServiceClient 之间建立紧密耦合。为了对ArticleViewModel 进行单元测试just,需要模拟此依赖项。如果有 IMyServiceClient,那么您可以将其提供给班级:

public ArticleViewModel
{
    private IMyServiceClient ServiceClient { get; set; }

    public ArticleViewModel(IMyServiceClient serviceClient)
    {
        this.ServiceClient = serviceClient;
    }

    // etc.
}

然后该类中的代码不会创建新的服务客户端,它只会使用该属性中的那个。

然后在单元测试中,您将创建一个 IMyServiceClient 的模拟,在该模拟上定义预期行为,并将其提供给正在测试的对象。你如何做到这一点取决于模拟库。 Rhino Mocks 中的一个简单示例可能如下所示:

// arrange
var serviceClient = MockRepository.GenerateMock<IMyServiceClient>();
serviceClient.Stub(c => c.GetArticle(Arg<string>.Is.Anything)).Return("Article 1");

var model = new ArticleViewModel(serviceClient);

// act
var result = model.LoadArticle("Thomas");

// assert
Assert.AreEqual("Article 1", result);

这里的想法是单元测试只测试LoadArticle 方法,而不是该方法调用的依赖项。这些依赖项提供了预期的行为,并根据这些预期的行为检查结果。

注意:没有什么可以阻止单元测试提供MyServiceClient实际实现,而不是模拟。单元测试项目只需要该服务的配置即可工作。 (单元测试项目是应用程序宿主,它们可以有App.config 文件。)这将是一个集成测试而不是单元测试,但可以对结果做出相同的断言。

【讨论】:

    【解决方案2】:

    是的,我认为你是对的,我建议 IMyService 的构造函数参数,你可以使用它来将模拟注入对象进行测试。

    进一步!我建议不要使用自动生成的服务客户端。如果您将代码复制并粘贴到您自己的类中,您可以使其实现 IMyService 并有效地隐藏它使用 WCF、直接进入数据库或是真实代码中的模拟对象的事实。

    这将允许您将 Mock 注入 WPF 以进行 UI 测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多