标签: testability

Java:如何测试调用System.exit()的方法?

我有一些方法可以调用System.exit()某些输入.不幸的是,测试这些情况会导致JUnit终止!将方法调用放在新线程中似乎没有帮助,因为System.exit()终止JVM,而不仅仅是当前线程.是否有任何常见的处理方式?例如,我可以替换存根System.exit()吗?

[编辑]有问题的类实际上是一个命令行工具,我试图在JUnit中测试.也许JUnit根本不适合这份工作?建议使用补充回归测试工具(最好是与JUnit和EclEmma完美集成的东西).

java junit multithreading unit-testing testability

187
推荐指数
9
解决办法
8万
查看次数

继承与可测试性的组合

在设计我的对象时,我发现从可测试性的角度来看,组合是更好的选择.原因是,如果需要的话,我可以在运行单元测试时模拟部分组合结构.如果我有一个继承层次结构,这是不可能的.

我想知道其他人是否也发现这是喜欢作曲的理由.还有什么其他可测试性陷阱,因为使用了继承?

inheritance testability composition

26
推荐指数
4
解决办法
7651
查看次数

扩展方法是否隐藏依赖关系?

所有,

想要对此有所了解.最近,我在设计/开发时越来越多地成为"纯粹的"DI/IOC原则的订户.其中一部分(很大一部分)涉及确保我的类之间几乎没有耦合,并且它们的依赖关系是通过构造函数解决的(当然还有其他方法来管理它,但你明白了).

我的基本前提是扩展方法违反了DI/IOC的原则.

我创建了以下扩展方法,以确保插入到数据库表中的字符串被截断为正确的大小:

public static class StringExtensions
{
    public static string TruncateToSize(this string input, int maxLength)
    {
        int lengthToUse = maxLength;
        if (input.Length < maxLength)
        {
            lengthToUse = input.Length;
        }

        return input.Substring(0, lengthToUse);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以从另一个类中调用我的字符串,如下所示:

string myString = "myValue.TruncateThisPartPlease.";
myString.TruncateToSize(8);
Run Code Online (Sandbox Code Playgroud)

不使用扩展方法对此进行公平的翻译将是:

string myString = "myValue.TruncateThisPartPlease.";
StaticStringUtil.TruncateToSize(myString, 8);
Run Code Online (Sandbox Code Playgroud)

使用上述任一示例的任何类都无法独立于包含TruncateToSize方法的类(除了TypeMock)进行测试.如果我没有使用扩展方法,并且我不想创建静态依赖项,它看起来更像:

string myString = "myValue.TruncateThisPartPlease.";
_stringUtil.TruncateToSize(myString, 8);
Run Code Online (Sandbox Code Playgroud)

在最后一个示例中,_stringUtil依赖项将通过构造函数解析,并且可以测试该类,而不依赖于实际的TruncateToSize方法的类(可以很容易地模拟).

从我的角度来看,前两个示例依赖于静态依赖(一个显式,一个隐藏),而第二个反转依赖性并提供减少的耦合和更好的可测试性.

那么扩展方法的使用是否与DI/IOC原则相冲突?如果您是IOC方法的订阅者,您是否避免使用扩展方法?

extension-methods dependencies inversion-of-control testability c#-3.0

16
推荐指数
2
解决办法
1788
查看次数

使c ++代码易于测试的模式

您是否应该设计代码以使测试更容易?如果是这样的话,如何设计c ++代码以便于测试.

  • 你如何在c ++中应用依赖注入?
  • 我应该使用纯接口类作为基础来实现类,以简化伪测试对象的创建?
    • 这会迫使我制作很多虚拟方法.这会影响性能吗?
  • 在c ++中设计可测试性时我还应该考虑什么?

c++ testing dependency-injection testability

11
推荐指数
2
解决办法
3076
查看次数

带有继承和mixins的Scala可测试代码

我用Java开发了很多代码,并涉足Groovy和Haskell,现在我已经把我带到了Scala.

我对Scala的功能方面感到相对舒服,但我发现自己在Scala中的面向对象设计上有些不稳定,因为它感觉与Java有点不同,特别是由于特性/混合.

我的目标是编写尽可能可测试的代码,这在我的Java开发中一直都是关注的

  • 尽可能的不变性
  • 倾向于由构造者注入状态
  • 总是去构成而不是继承(受SO影响很大,可能对此帖子过度反应)

现在我正试图在这个新的Scala领域站起来,我很难弄清楚我应该采取什么方法,特别是我是否应该为某些目的开始使用继承.

编程Scala(Wampler和Payne; O'Reilly,第2版)有一个考虑因素("良好的面向对象设计:一个题外话"),我已经阅读了很多关于SO的帖子,但我还没有看到明确提到可测试性的设计考虑因素.本书提供了有关使用继承的建议:

  1. 抽象基类或特征由具体类(包括案例类)分为一级.
  2. 除了两种情况外,具体类永远不会被子类化:
    • 混合在特征中定义的其他行为的类(...)
    • 仅测试版本,以促进自动化单元投影.
  3. 当子类化似乎是正确的方法时,考虑将行为划分为特征并改为混合这些特征.
  4. 永远不要跨父子类型边界拆分逻辑状态.

对SO的一些挖掘也表明,有时混合比组合更好.

所以本质上我有两个问题:

  1. 是否有一些常见的情况,即使考虑可测试性,使用继承会更好?

  2. 混合是否提供了增强代码可测试性的好方法?

java oop unit-testing scala testability

9
推荐指数
1
解决办法
941
查看次数

Scala:如何测试调用System.exit()的方法?

我一直在开发一个命令行工具,它在某些输入上调用System.exit()(不想使用异常而不是).

我熟悉Java:如何测试调用System.exit()的方法?它是最优雅的方法.

不幸的是,它是不够纯,因为我不得不添加的依赖关系到系统的规则,JUnit的接口

System.exitspecs2中是否有任何常见的处理模式,这种模式比我目前使用specs2的方法更纯粹?

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;

public class ConverterTest {
    @Rule
    public final ExpectedSystemExit exit = ExpectedSystemExit.none();

    @Test
    public void emptyArgs() {
        exit.expectSystemExit();
        Converter.main(new String[]{});
    }

    @Test
    public void missingOutArgument() {
        exit.expectSystemExitWithStatus(1);
        Converter.main(new String[]{"--in", "src/test/resources/078.xml.gz"});
    }
}
Run Code Online (Sandbox Code Playgroud)

unit-testing scala testability sbt specs2

9
推荐指数
1
解决办法
2125
查看次数

应该避免使用静态类,因为它会使依赖注入困难吗?

负责创建"核心"库集的人创建了一组静态类,提供来自日志记录,审计和常见数据库访问方法的各种实用程序.

我个人认为这很臭,因为我们现在有一组很难测试的Core库,因为我不能模拟/存根这些类或者对它们的构造函数进行任何注入.

我想我可以使用TypeMock将它们存在,但我宁愿免费使用它.

你怎么看?

编辑

如果你不认为他们很难测试,你可以给出一个如何测试它们的例子.这些静态类实例化其他类型以执行其功能.

c# dependency-injection mocking testability

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

在Windows客户端(WPF)应用程序中执行依赖注入的正确方法

我习惯于在Web应用程序中使用IoC/DI - 主要是使用MVC3的Ninject.我的控制器是为我创建的,充满了所有依赖关系,子依赖关系等.

但是,胖客户端应用程序的情况有所不同.我必须创建自己的对象,或者我必须恢复到服务定位器样式方法,我要求内核(可能通过某个接口,允许可测试性)给我一个完整的依赖项对象.

但是,我已经看到Service Locator被描述为反模式的几个地方.

所以我的问题是 - 如果我想在我的胖客户端应用程序中受益于Ninject,是否有更好/更正确的方法来获得所有这些?

  • 可测性
  • 适当的DI/IoC
  • 可能的耦合量最小

请注意我不只是在这里讨论MVVM并将视图模型放入视图中.这特别是需要从内核提供存储库类型对象,然后从该存储库中提取的实体注入了功能(当然数据来自数据库,但它们也需要一些对象作为参数,具体取决于状态世界,Ninject知道如何提供).我可以以某种方式做到这一点,而不会将存储库和实体都作为不可测试的混乱吗?

如果有什么不清楚,请告诉我.谢谢!

编辑7月14日

我确信提供的两个答案可能是正确的.然而,我身体的每一根纤维都在对抗这种变化; 其中一些可能是由于缺乏知识造成的,但也有一个具体原因导致我无法看到这种做事方式的优雅;

我没有在原始问题中解释得这么好,但问题是我正在编写一个库,将被几个(首先是4-5,可能更晚)的WPF客户端应用程序使用.这些应用程序都在相同的域模型等上运行,因此将它们保存在一个库中是保持DRY的唯一方法.但是,该系统的客户也有可能编写自己的客户端 - 我希望他们有一个简单,干净的库来与之交谈.我不想强迫他们在他们的作文根中使用DI(在他的书中使用像Mark Seeman这样的术语) - 因为与他们相比,只需要新建一个MyCrazySystemAdapter()并使用它就可以使事情复杂化.

现在,MyCrazySystemAdapter(因为我知道人们会在这里不同意我选择的名称)需要由子组件组成,并使用DI组合在一起.MyCrazySystemAdapter本身不需要注入.它是客户端与系统通信所需的唯一接口.因此,一个客户应该得到其中一个,DI就像魔术一样在幕后发生,并且该对象由许多不同的对象使用最佳实践和原则组成.

我确实意识到这将成为一种想要做事的有争议的方式.但是,我也知道将成为此API客户的人员.如果他们发现他们需要学习并连接DI系统,并在他们的应用程序入口点(Composition Root)中提前创建他们的整个对象结构,而不是新建一个对象,他们会给我中指和直接搞乱数据库并以你难以想象的方式搞砸了.

TL; DR:为客户端提供结构合理的API太麻烦了.我的API需要提供一个单独的对象 - 使用DI和适当的实践在幕后构建 - 他们可以使用.现实世界有时胜过为了坚持模式和实践而向后建造一切的愿望.

dependency-injection ninject testability thick-client service-locator

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

哪一个在react/redux应用程序中保存服务实例?

假设我在Redux中编写应用程序,我的任务是使用第三方库添加日志记录.其API如下:

function createLogger(token) {
    // the logger has internal state!
    let logCount = 0;

    return {
        log(payload) {
            logCount++;            // modify local state

            fetch('/someapi', {    // ship payload to some API
                method: 'POST',
                body: payload
            });
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

然后我会使用这样的库:

let logger = createLogger('xyz');
logger.log('foobar');
Run Code Online (Sandbox Code Playgroud)

我绝对想在应用程序初始化期间只创建一次logger实例.但问题是:我在哪里存储记录器实例

第一个是将它放在商店的某个地方.但这是个好主意吗?正如我在代码中演示的那样,logger对象是有状态的,它在闭包中存储了一个计数器.我没有像使用不可变对象那样获得新实例.我们知道,只应通过纯缩减器函数修改状态.

其他可能性是在redux中间件闭包中的某处创建实例,或者只创建一个全局变量,这在可测试性方面显然是邪恶的.

是否有最佳实践(我认为)相当常见的情况?

javascript testability reactjs redux

6
推荐指数
1
解决办法
1035
查看次数

在C++项目中,TDD可能/生产力足够吗?

我想知道你们中的任何人是否在你的c ++项目中使用TDD以及它与C#和Java等托管语言相比如何表现.你们用什么框架来自动化c ++项目的测试?

c++ tdd unit-testing testability

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

Node.js:导出类/原型与实例

当我用Java进行大多数编程时,我发现在Node.js模块而不是对象实例中导出类非常引人注目,例如:

class Connection {
    constructor(db) {
        this.db = db;
    }
    connect(connectionString) {
        this.db.connect(connectionString);
    }
}
exports.Connection = Connection;
Run Code Online (Sandbox Code Playgroud)

由于这样做需要跨相关模块多次实例化该类,因此我仍然需要导出一个已经存在的实例,以供其余生产代码使用。我在同一模块中执行此操作:

exports.connection = new Connection(require("mongoose"));
Run Code Online (Sandbox Code Playgroud)

这允许一些可测试性,因为可以在测试中交换真正的依赖项:

const Connection = require("./connection").Connection;

describe("Connection", () => {
    it("connects to a db", () => {
        const connection = new Connection({connect: () => {}});
        // ...
    });
});
Run Code Online (Sandbox Code Playgroud)

这种方法有效,但是当我在这里混合两种模式时却感觉很奇怪:导出原型(用于单元测试)和实例(用于生产代码)。这可以接受吗?我应该继续执行此操作还是更改为其他内容?如果是这样,首选模式是什么?

javascript dependency-injection testability node.js node-modules

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

在C#中使用#if debug指令是否可以?

我们有一个类,类似于以下内容:

public class Processor
{
    //set timeout in seconds
    private const int TIMEOUT = 600;

    public void Process()
    {
        //DO SOMETHING HERE

        //CHECK TO SEE IF TIMEOUT HAS BEEN HIT
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,我们想编写单元测试,以查看在指定的时间后是否发生超时.显然,我们不希望每次运行测试时都要等待10分钟.考虑到这一点,我的问题是:

我们如何管理这个值,使其在测试期间可能是10秒,但在生产中可能需要10分钟?有很多明显的方法可以做到这一点,但我正在努力确定最干净的方式.我们应该将其作为财产公开吗?包含它作为构造函数参数?将其作为方法参数包含在内?使用编译器指令?

c# testability

2
推荐指数
1
解决办法
2833
查看次数