我有一个关于工厂方法单元测试的问题。假设我们有以下代码并希望测试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();
}
看起来这是更好的方式。但是,我不喜欢我们必须创建工厂接口、工厂、工厂设置器并使测试变得更加复杂,只为了测试一行代码。
你对此有什么想法?你更喜欢什么?你有其他测试方法吗?