小编Abe*_*ich的帖子

单元测试私有方法:Facade模式

许多开发人员认为测试私有方法是个坏主意.但是,我发现的所有示例都基于私有方法是私有的,因为调用它们可能会破坏内部对象的状态.但这不仅是隐藏方法的理由.

我们来看看Facade模式.我的班级用户需要2种公共方法.它们太大了.在我的示例中,他们需要从数据库的BLOB加载一些复杂的结构,解析它,填充一些临时COM对象,运行用户的宏来验证和修改这些对象,以及将修改后的对象序列化为XML.单个metod的相当大的功能:-)这两个公共方法都需要这些操作.所以,我创建了大约10个私有方法,并且有2个公共方法可以调用它们.实际上,我的私人方法不一定是私人的; 他们不会破坏实例的内部状态.但是,当我不习惯测试私有方法时,我有以下问题:

  1. 发布它们意味着用户的复杂性(他们有一个他们不需要的选择)
  2. 我无法想象TDD风格如此庞大的公共方法,当你要编写500多行代码只是为了返回一些东西(甚至不是真正的结果).
  3. 从数据库中检索这些方法的数据,并且测试与DB相关的功能要困难得多.

当我测试私有方法时:

  1. 我不会发布会让用户感到困惑的细节.公共接口包括2种方法.
  2. 我可以用TDD风格工作(逐步编写小方法).
  3. 我可以使用测试数据覆盖大部分类的功能,而无需数据库连接.

有人可以形容,我做错了什么?我应该使用什么样的设计来获得相同的奖金,而不是测试私人方法?

更新:在我看来,我已经提取了我能够进行的其他课程.所以,我无法想象我还能提取什么.从数据库加载由ORM层执行,解析流,序列化为XML,运行宏 - 一切都由独立类完成.该类包含非常复杂的数据结构,搜索和转换的例程,以及对所有提到的实用程序的调用.所以,我不认为可以提取其他东西; 否则,它的责任(关于数据结构的知识)将在类之间划分.

所以,我现在看到的最好的解决方法是分成两个对象(Facade本身和真实对象,私有方法变为公共)并将真实对象移动到某个地方,没人会试图找到它.在我的情况下(Delphi)它将是一个独立的单元,在其他语言中它可以是一个单独的名称空间.其他类似的选项是2个接口,感谢您的想法.

tdd unit-testing

8
推荐指数
1
解决办法
4428
查看次数

MSBuild:如何获得引发的警告数量?

有一个MSBuild脚本,包括Delphi和C#项目的数字,单元测试等.

问题是:如果警告被引发,如何标记构建失败(出于测试目的,而不是发布版本)?在自定义任务中使用LogError而不是LogWarning似乎不是一个好的选择,因为构建应尽可能多地测试(直到真正的错误)在一段时间内尽可能多地报告警告(构建项目在CruiseControl.NET中使用) ).

可能是,解决方案是创建我自己的记录器,将内部存储警告标志,但我无法找到是否有一种方法在构建结束时读取此标志?

PS收到警告后立即使构建失败没有问题(Delphi编译器输出由自定义任务处理,而/ warnaserror可用于C#),但所需的行为是"构建所有内容;收集所有警告;失败构建" "报告所有警告,不仅仅是关于第一个警告.

PPS至于我真的不需要警告的数量,而只是它们存在的标志,我决定简化信令机制,并使用琐碎的Mutex而不是共享内存.代码如下:

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Threading;

namespace Intrahealth.Build.WarningLogger
{
    public sealed class WarningLoggerCheck : Task
    {
        public override bool Execute()
        {
            Log.LogMessage("WarningLoggerCheck:" + mutexName + "...");
            result = false;
            Mutex m = null;
            try
            {
                m = Mutex.OpenExisting(mutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                result = true;
            }
            catch (Exception)
            {
            }

            if (result)
                Log.LogMessage("WarningLoggerCheck PASSED");
            else
                Log.LogError("Build log contains warnings. Build is FAILED");

            return result;
        }

        private bool result = true; …
Run Code Online (Sandbox Code Playgroud)

cruisecontrol.net msbuild

5
推荐指数
1
解决办法
2970
查看次数

标签 统计

cruisecontrol.net ×1

msbuild ×1

tdd ×1

unit-testing ×1