NUnit的 - 如何测试实现一个特定的接口的所有类接口、测试、NUnit

2023-09-02 01:54:40 作者:你是我心中的一道疤

如果我有接口IFoo的,并且有实现它几类,什么是最好的/最优雅/巧对接口测试所有这些类的方式?

If I have interface IFoo, and have several classes that implement it, what is the best/most elegant/cleverest way to test all those classes against the interface?

我想,以减少测试code复制,但仍然忠于单元测试的原则。

I'd like to reduce test code duplication, but still 'stay true' to the principles of Unit testing.

你会怎么考虑的最佳做法?我使用NUnit的,但我想任何单元测试框架的例子是有效的

What would you consider best practice? I'm using NUnit, but I suppose examples from any Unit testing framework would be valid

推荐答案

如果您有类实现任何一个接口,那么它们都需要实现该接口中的方法。为了测试这些类,你需要创建一个单元测试类,每一类。

If you have classes implement any one interface then they all need to implement the methods in that interface. In order to test these classes you need to create a unit test class for each of the classes.

让我们去一个更聪明的路线,而不是;如果你的目标是为避免code和测试code复制您可能要创建一个抽象类,而不是处理的经常性 code。

Lets go with a smarter route instead; if your goal is to avoid code and test code duplication you might want to create an abstract class instead that handles the recurring code.

例如。您有以下接口:

public interface IFoo {

    public void CommonCode();

    public void SpecificCode();

}

您可能要创建一个抽象类:

You might want to create an abstract class:

public abstract class AbstractFoo : IFoo {

    public void CommonCode() {
          SpecificCode();
    }

    public abstract void SpecificCode();

}

测试,很容易;在测试类实现抽象类无论是作为一个内部类:

Testing that is easy; implement the abstract class in the test class either as an inner class:

[TextFixture]
public void TestClass {

    private class TestFoo : AbstractFoo {
        boolean hasCalledSpecificCode = false;
        public void SpecificCode() {
            hasCalledSpecificCode = true;
        }
    }

    [Test]
    public void testCommonCallsSpecificCode() {
        TestFoo fooFighter = new TestFoo();
        fooFighter.CommonCode();
        Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
    }
}

...还是让测试类扩展抽象类本身是否适合你的想象。

...or let the test class extend the abstract class itself if that fits your fancy.

[TestFixture]
public void TestClass : AbstractFoo {

    boolean hasCalledSpecificCode;
    public void specificCode() {
        hasCalledSpecificCode = true;
    }

    [Test]
    public void testCommonCallsSpecificCode() {
        AbstractFoo fooFighter = this;
        hasCalledSpecificCode = false;
        fooFighter.CommonCode();
        Assert.That(fooFighter.hasCalledSpecificCode, Is.True());
    }        

}

有一个抽象类,照顾普通code,一个接口意味着给出了一个更清洁的code设计。

Having an abstract class take care of common code that an interface implies gives a much cleaner code design.

我希望这是有道理的你。

I hope this makes sense to you.

作为一个方面说明,这被称为常见的设计模式在 模板方法模式 。在上面的例子中,模板方法是通用code 方法和具体code 被称为存根或钩。我们的想法是,任何人都可以扩展行为,而不需要知道的幕后东西

As a side note, this is a common design pattern called the Template Method pattern. In the above example, the template method is the CommonCode method and SpecificCode is called a stub or a hook. The idea is that anyone can extend behavior without the need to know the behind the scenes stuff.

很多框架依靠这种行为模式,如: ASP.NET ,你必须实现钩在一个页面或用户控件,例如生成的的Page_Load 方法,这就是所谓的加载事件,模板方法调用背后的挂钩场景。有这多很多的例子。基本上任何东西,你必须实现一个使用单词负荷,初始化,或渲染被称为由模板方法。

A lot of frameworks rely on this behavioral pattern, e.g. ASP.NET where you have to implement the hooks in a page or a user controls such as the generated Page_Load method which is called by the Load event, the template method calls the hooks behind the scenes. There are a lot more examples of this. Basically anything that you have to implement that is using the words "load", "init", or "render" is called by a template method.

 
精彩推荐
图片推荐