可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a situation where I need to mock some code in production. This is for making one part of code, work in half functionality.
I have to choose to write an empty classes (to implement the interface) , or use a mocking system like moq.
So the question is, do the mocking systems hit the performance, or break some readability of the production code?
update
example:
interface IRocketSystem
{
void LaunchTheRocket();
}
class SimulationRocketSystem:IRocketSystem
{
...
}
class RocketSystem:IRocketSystem
{
...
}
i found that i have a SimulationRocketSystem classes in production, that small and don't have a lot in the body. the mock system is have one line of code ( new Mock < IRocketSystem >().Object ) to replace classes like this.
the pros for mocking:
less empty classes in project.
回答1:
Sounds like a Null Object. I don't believe in using mocking frameworks for this for two reasons.
First, it hurts readability. You implementing the interface with an appropriately named empty class, then you document the intent inside that class. On the other hand, if you use a mocking framework, your documentation needs to be embedded in the code somewhere. Furthermore, it will be confusing as people tend to expect mocks in test code and not understand your intent for using mocks.
Second, you have to consider what happens if someone modifies the interface. What if a method is added? Should it default to returning null - as some frameworks would do? What if the method must return some specific return value according to the interface contract. If you have a concrete implementation, then the compiler will at least protect you somewhat. If you use a mocking framework, you may be out of luck.
回答2:
A mock object is something you use for testing, as it will let you assert that it was called correctly. It sounds to me that what you're looking for is more like a stub or a proxy object.
Since you will eventually implement the class in question it would make little sense to have a mock framework do it for you IMO. Why not just create the class and implement it as needed.
回答3:
What's wrong with an empty class?
Indeed, it will be replaced with a real class, so you may as well start with a real class.
I think putting mock code of any kind outside tests is a bad policy.
回答4:
You call it mock, but it seems like what you are doing is just proper separation of concern.
It is a good thing to use polymorphism over if-statements to control what should happen.
Example, say if you want logging to be optional. The imperative approach is to supply a boolean isLogging
. Then every time check the boolean like if (isLogging) { ...logging code... }
.
But if you instead separate the actual log code as a concern for another object, then you can set that object to one that does what you want. Besides having a null-routed logger that represent logging disabled and one that actually write to a file, it also allow you to supply a logging object that writes to a database instead of a file, it allows you to add features to the logger, such as log-file rotation.
It's simply good object oriented programming.
回答5:
It's perhaps a little unusual, so I would be clear in my comments etc. that this is required functionality. Otherwise someone's going to be very confused as to how test code has made it to production!
As to performance, as ever, you need to measure this since it's so specific. However, I would hazard a guess that as you're mocking functionality you've not written, it may well be much faster than your mocked-out implementation. That's something you may need to educate your users about, since when you provide a final functioning implementation, they could well see a performance hit :-)
The real solution is to provide a dummy implementation to an existing interface, and to provide the real implementation later on.
回答6:
I don't really know about performance issues. But IMHO, you must be really careful about readability. Isn't it better to declare one or more interfaces and implement it two different ways?
--EDIT
Mocking might be easier, and use less lines of code, but it increases learning curve of your code. If a new guy comes and see your code, he will require more time to understand. Personally, I'd think it is a not yet implemented feature of the code. But if there was another interface implementation, or some other good design decision, I'd "get it" much faster and would feel more secure with changing the code.
Well, that's a personal opinion. Your code will be using a different pattern from what is expected. It's similar to "convention over configuration". If you're not using the convention, you should have a harder time configuring it (in your case, documenting and making clear what you're doing).
回答7:
My advice - don't put it in production. Don't ever put anything in production that can slow it down, break it, or otherwise cause you to lose your job :)
But more important than what I think is what is your company policy and what does your manager think? You should never think of making a decision like this on your own - it's called CYA.
回答8:
I have to choose to write an empty classes, or use a mocking system like moq.
Wrapping it up in a dedicated facade/adapter component and using inner classes should be enough. If your empty classes need to be passed around the system you have a problem.