简体   繁体   中英

Moq c# private method to throw an exception

Given this class:

public class MyClass 
{  
     private void MyMethod()  
     {  
         //...
     }  

     public void Execute()
     {  
        try
        {
             //...  
             MyMethod();  
             //... 
        }  
        catch(Exception e)  
        {  
            ...  
        }   
     }  
}

How can I Mock MyMethod to throw an OutOfmemoryException ?

EDIT 1:

Given the next situation where MyMethod loads some data from database, and some unpredicted error occurs, MyMethod will throw an exception. I want to be able to unit test that situation. In my case the catch clause from execute method.

I don't use Moq, so it's possible that there's some way you can do it - but I'd argue that if you need to, you're doing mocking wrong.

You should usually be mocking dependencies - and you can't be depending on their private members from the class you're trying to test, can you? Typically I'd mock an interface - occasionally it can be useful to mock a class, but I typically don't. If you're calling into some dependency and you want the result of that call to be an OutOfMemoryException , just make that public call throw the exception.

If you feel you've got a good reason to want to mock a private method, please give more details about your context.

您只能模拟公共属性和公共方法(无论是在接口中还是直接在类中定义)。

What you run into is basically a limitation of the primitive waqy Mock works for mocking.

There are some commercial frameworks out there that work around that - JustMock from Telerik being the most reasonable priced one. They work by attaching themselves as profilers and replacing the bytecode executed - so they really MOCK the methods.

MOCK - and all others excelpt a handfull - work by basically subclassing / implementing and you can not subclass a private or non virtual method. THat makes them useless to mock any properly defined sealed object that should not be subclassable - you have to program your objects open which then allows all kinds of possible abuse.

They also can not mock static methocs- which the few ones can. This is very usefull because it allows you for example to Mock a call to DateTime.UtcNow so it always returns a SPECIFIC time, which may be needed in a unit test.

So, sorry, there is no way to do that with Mock.

I've not had a chance to try this, but we use Moq some where I work and I've been struggling with stuff like this as well. First off, Moq is not based off of public, private, etc. per se. It is based on what your test class has visibility into. We're doing a lot with VB.net so my recent memory is colored by that (ie take this with a grain of salt). 1) In order to test "private" methods--Try to make your test assembly have visibility into the assembly that contains your classes under test. Look here for information on how to do this. You will need to change them to "internal" (same as friend in vb.net). In classic TDD you (generally) try to have everything in your class under test visibile to the test itself. 2)Once you have visibility into the MyMethod, you should be able to mock out a response of any kind of exception that you need (presuming you can instantiate and throw it). 3) Other ideas are to create an internal class in your test code that extends the class under test and override the method that you want to control from inside your test class.

Sometimes, especially with legacy code, you have to do some ugly things to make the code testable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM