2014-10-10 74 views
0

在我的生产代码中我有一个工厂,这个工厂应该在我的测试代码中被嘲笑。 我有两个工厂实现的接口:Java焊接CDI替代工厂

public interface FtpTransferFactory { 

    FtpTransfer createFtpTransfer(String host, String machine); 

} 

生产代码:

@Default 
public class FtpTransferFactoryImpl implements FtpTransferFactory { 

    public FtpTransferFactoryImpl() { 
    } 

    @Override 
    public FtpTransfer createFtpTransfer(final String host, final String machine) { 
    return new FtpTransfer(); // Some real ftp transfer object 
    } 

} 

测试代码:

@Alternative 
public class FtpTransferFactoryTestImpl implements FtpTransferFactory { 

    @Override 
    public FtpTransfer createFtpTransfer(String host, String machine) { 
    return ...; // Some real ftp transfer object, with different settings (test env) 
    } 

} 

在位于的src /测试/资源的beans.xml:

<alternatives> 
    <class>engine.FtpTransferFactoryTestImpl</class> 
</alternatives> 

我的实现类:

@Default 
public class SomeClass 
    /** Ftp Factory */ 
    @Default 
    @Inject 
    private FtpTransferFactory ftpFactory; 

    ... 
} 

当我执行我的单元测试我的实现类仍与生产工厂,而不是工厂测试结束。但是,当我将-element放入我的src/main/resources(生产)时,它确实有效。但我不希望这样,因为我将测试代码放入生产代码中。我见过几个教程通过这种方法做...我做错了什么?

+0

为什么不使用mockito进行这种测试? – maress 2014-10-10 08:50:49

+0

因为我只想用其他设置(测试时)初始化我的“FtpTransfer”对象。我想用真实的物体,因为我不想嘲笑它。 – Velth 2014-10-10 08:57:48

+0

您是否需要运行时信息(用户输入)来创建FtpTranfer实例,还是主机和机器可配置的?如果是后者,则可以摆脱工厂并使用生产者方法。 – 2014-10-11 11:08:44

回答

1

src/main/resourcessrc/test/resources中的类是两个独立的bean部署档案(BDA)。 A beans.xml描述符仅影响当前的BDA。

所以你的<alternative>定义只影响你的测试类,但不影响你的生产类。

如果您使用CDI 1.1,则可以通过添加@Priority注释来制作替代全局(即为应用程序中的所有BDA激活它)。

在CDI 1.0上,您可以尝试使用@Specializes而不是@Alternative覆盖您的默认bean。

+0

@Specializes +1 ...好主意! – 2014-10-11 11:07:05

+0

如果我理解正确 - 这意味着您可以'永远'注入生产代码的替代类?这不是CDI的目标之一吗?但是,我无法实现解决方案,我会使用替代方案,专业方案或优先级。我将工厂更改为生产者方法,并从配置中读取所有设置 - 运行单元测试时会对其进行处理。不管怎么说,还是要谢谢你。 – Velth 2014-10-14 06:45:38