Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock non virtual methods?

Tags:

c#

.net

moq

[TestMethod]
public void TestMethod1()
{
    var mock = new Mock<EmailService>();
    mock.Setup(x => x.SendEmail()).Returns(true);
    var cus = new Customer();
    var result = cus.AddCustomer(mock.Object);
    Assert.IsTrue(result);
}

public class Customer
{
    public bool AddCustomer(EmailService emailService)
    {
        emailService.SendEmail();
        Debug.WriteLine("new customer added");
        return true;
    }
}

public class EmailService
{            
    public virtual bool SendEmail()
    {
        throw  new Exception("send email failed cuz bla bla bla");
    }
}

The EmailService.SendEmail method must be virtual to mock it. Is there any way to mock non virtual methods?

like image 373
hbmaam Avatar asked Jul 31 '12 10:07

hbmaam


People also ask

Can you mock non-virtual methods gMock?

gMock can mock non-virtual functions to be used in Hi-perf dependency injection. In this case, instead of sharing a common base class with the real class, your mock class will be unrelated to the real class, but contain methods with the same signatures.

Can you override a non-virtual method?

You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.

Can we override non-virtual method in Java?

You can override any method of a class, the question is really how to access the non-virtual method, or should I have made the method virtual in the first place. With a virtual method, you always access the overridden method regardless of the class variable used to reference it.

Can you override a virtual method?

A virtual method can be created in the base class by using the “virtual” keyword and the same method can be overridden in the derived class by using the “override” keyword.


3 Answers

Moq cannot mock non virtual methods on classes. Either use other mocking frameworks such as Type mock Isolator which actually weaves IL into your assembly or place an interface on EmailService and mock that.

like image 199
aqwert Avatar answered Oct 01 '22 02:10

aqwert


Mocking non virtual methods involves the use of low level profiler API. At the moment I think the only options available are :

  • TypeMock
  • JustMock

both are commercial, even if JustMock have a lite edition, mocking non virtual methods are available just with the commercial version. As pointed in the comments there is something from Microsoft research, in the project Pex and Moles

like image 28
Felice Pollano Avatar answered Oct 01 '22 01:10

Felice Pollano


Updated july 2020: pose Has been abandoned, current recommendation is: https://github.com/riezebosch/Unmockable Thanks to @Customizer for pointing out.

I was also checking out https://github.com/Serg046/AutoFake which seems viable from @Serg046 —— Use pose. Allows you to replace any method including static or non virtual. Fairly new project, but fully open source MIT license. https://github.com/tonerdo/pose

like image 22
James Reategui Avatar answered Oct 01 '22 02:10

James Reategui