在测试之外使用模拟对象,不好的做法吗? [英] Using mock objects outside of testing, bad practice?

查看:40
本文介绍了在测试之外使用模拟对象,不好的做法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个有很多外部服务消息传递的项目.仅需稍微夸张"地描述它的一个好方法就是应用程序,该系统必须将消息发送到Flicker API,Facebook API和Netflix API.

I'm working on a project where there is a lot of external service messaging. A good way to describe it in only a slightly "hyperbolas" way would be an application where the system has to send messages to the Flicker API, the Facebook API, and the Netflix API.

为支持断开连接的方案,日志记录问题,开发人员的可用性,配置等...我已经尝试过使用大量使用泛型和表达式树的方法.最终结果如下:

To support disconnected scenarios, logging concerns, developer usability, configuration, etc... I've experimented using an approach which heavily uses generics and expression trees. The end result looks like this:

Messenger<NetflixApi>.SendCustom( netflix => netflix.RecommendMovie("my message"));

总体上,我对最终结果感到满意,但感觉到我犯了一个错误,或者在测试和脱机方案方面忽略了某个设计原则.

Overall I'm happy with the end result but feel like I've made a mistake, or overlooked a design principal someplace with regards to testing and disconnected scenarios.

在测试过程中,无论是自动化的,基于单元的还是基于人工的,我都实现了一个对象工厂,该工厂最初使用DI来在实时模式"下执行正确的操作,并使用Mocks来提供一种无菌信使,该信使不会在测试模式下什么也做不了.

During testing, whether automated, unit, or human based, I've implemented an object factory that initially uses DI to perform the correct action in "Live mode" and used Mocks to provide a sort of sterile messenger that doesn't do anything at all when in a testing mode.

我只看过或读过Mocks在纯TDD模式下使用,而不是被用作愚蠢的对象.我所看到的方法将围绕存根或模拟HTTP通讯功能,而我正在使用的所有API都依赖于该通讯功能.

I've only seen or read about Mocks being used in pure TDD mode and not being used to be sort of a dumb object. The approaches I've seen would revolve around stubbing or mocking out the HTTP communication functionality which all the APIs I'm using depend on.

我主要担心的是,我希望连接的所有不同服务最终将不得不做很多细化的工作来代替特定的HTTP实现,如果我使用存根方法,则每个方法都有3个类这些服务(IService,ConcreteService,StubService)中的任何一项,并且在实施新方法或进行任何更改时对其进行维护将是真正的PITA.

My main concern is that will all the different services I expect to connect to I'd end up having to do a lot of granular work substituting specific HTTP implementation and if I used a stub approach I'd have 3 classes for each of these services( IService, ConcreteService, StubService ) and maintaining those when implementing a new method or changing anything would be a real PITA.

在当前的实现中,我正在使用Mocks免费获得无菌模式",而不必执行额外的任何工作以符合特定的测试原理.

In the current implementation I'm using Mocks to get "sterile mode" for free almost without having to implement anything extra just to conform to a certain testing principal.

问题是我缺少什么吗?我是否以更方便的方式违反了使用Mocks的设计原则?

The question is am I missing something? Did I violate a design principal using Mocks in a more... convenient way?

任何人都可以就如何从许多不同的外部服务中获得无菌模式提供任何建议,而又不会遇到很多麻烦吗?

Can anybody offer any advice on how to get a sterile mode out of many different outside services without jumping through a lot of hoops?

这个问题有意义吗?

感谢所有答案.

编辑#1:

我对最初的问题不清楚.任何null或模拟对象都只能在开发/调试/测试环境中使用.在生产中,发送这些消息的代码将是它们的实际实现.

I wasn't clear in my original question. Any null or mock objects are to be used purely in a development/debug/testing environment. In production the code that sends these messages will be the actual implementation of them.

我投票赞成所有人,因为针对此问题似乎有很多不同的解决方案,我将逐一探讨.

I voted everybody up because there seem to be a lot of different solutions to this problem and I'll be exploring each one.

请不要以为这个问题已经回答了,我将尽力获得尽可能多的建议.

Please don't think this question has been answered yet, I'd appreciate as much advice as I can get.

推荐答案

有一个称为Null Object的设计模式.空对象是实现接口的对象,因此可以在像您这样的场景中使用.

There is a design pattern called Null Object. A null object is an object that implements a Interface, so it could be used in an scenario like yours.

有关Null对象的重要一点是,不要在可能会破坏系统的位置返回null.

The important thing about the Null Object is that DON'T return null in places where that could break the system.

Null对象的目的是使某些东西无效且简单地实现,就像Mock一样,但要在生产环境中使用.

The purpose of the Null Object is to have a void and simple implementation of something, just like a Mock, but to be used in the production environment.

最简单的例子是这样的:

The most simple example is something like this:

class Logger{
 private static ILogger _Logger;

 static Logger(){
  //DI injection here
  _Logger = new NullLogger(); //or
  _Logger = new TraceLogger();
 }
}

interface ILogger{
 void Log(string Message);
}

internal class TraceLogger:ILooger{
 public void Log(string Message){
  //Code here
 }
}

internal class NullLogger{
 public void Log(string Message){
  //Don't don anything, in purporse
 }
}

我希望这可以为您提供帮助

I hope this could help you

这篇关于在测试之外使用模拟对象,不好的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆