c# - 如何对工厂方法进行单元测试?

标签 c# unit-testing

我有一个关于工厂方法单元测试的问题。 假设我们有以下代码并想测试 Foo.ToBar 方法。

class Bar
{
    public Bar(int someparam)
    {
    }
}

class Foo
{
    int m_someprivate;

    public Foo()
    {
        m_someprivate = 1;
    }

    public Bar TooBar()
    {
        return new Bar(m_someprivate);
    }
}

我看到了两种不同的方法。其中一个会是这样的

[Test]
void TooBarTest()
{
    Foo foo = new Foo();

    Bar result = foo.TooBar();

    Assert.AreEqual(new Bar(1), result);
}

非常简单。但是,我不喜欢它有两个原因

a) 我们在测试 Foo 类时无意中测试了 Bar 类的一部分。例如,如果 Bar 构造函数抛出异常,那么我们的测试将失败,这是错误的,因为 Foo 类很好。这是一个有问题的 Bar 类。

b) 我不喜欢在 Assert new Bar(1) 中使用生产代码。我宁愿使用一些常量而不是一些代码 例如,可能会根据某些外部状态(等)返回不同的结果。

我看到的另一种方法是基于独立工厂的创建,它将创建 Bar

class Bar 
{
    public Bar(int someparam)
    {
    }
}

interface IBarFactory
{
    Bar create(int someparam);
}

class BarFactory : IBarFactory
{
    public Bar create(int someparam)
    {
        return new Bar(someparam);
    }
}

class Foo
{
    int m_someprivate;
    BarFactory m_barFactory;

    public Foo()
    {
        m_someprivate = 1;
        m_barFactory = new BarFactory();
    }

    public Bar TooBar()
    {
        return m_barFactory.create(m_someprivate);
    }

    public void setBarFactory(BarFactory barFactory)
    {
        m_barFactory = barFactory;
    }
}


[Test]
void TooBarTest()
{
    Mockery mockery = new Mockery()
    IBarFactory barFactoryMock = mockery.NewMock<IBarFactory>();
    Expect.Once.On(barFactoryMock).Method("create").With(new Object[] { 1 }).Will(Return.Value(new Bar(1)); 

    Foo foo = new Foo();
    foo.setBarFactory(barFactoryMock);

    foo.ToBar();
}

看起来这是更好的方法。但是,我不喜欢我们必须创建工厂接口(interface)、工厂、工厂 setter 并使测试更复杂,只是为了测试 1 行代码。

您对此有何看法?你喜欢哪个?你有任何其他测试方法吗?

最佳答案

我同意 Tomas Jansson 的观点。此外,我会在构造函数中注入(inject) IBarFactory 而不是实例化 BarFactory。因此,您永远不必触摸 Bar 或 BarFactory。相反,您可以在测试时 stub IBarFactory。

关于c# - 如何对工厂方法进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6918061/

相关文章:

java - 对 Java 多线程套接字服务器进行单元测试

ruby-on-rails - 在 Ruby on Rails 中,您测试 Controller 和 View 还是大多数模型?

unit-testing - 测试测试?

c# - 是否可以在 Docker 容器中运行 Kinect V2?

c# - 区分卸载/安装和升级应用程序

java - 单元测试: how to pass my mock class in the read code

ios - 如何测试自定义 UINavigationController 行为

c# - 如何使用FileOpenPicker打开 'New File Dialog'? (UWP)

c# - 我的局部 View 每次都会导致我的应用程序崩溃

c# - 访问具有可变键名的 JSON 项