0

I have class that constructor calls a function in constructor. When I create mock for this class then function is called from constructor. I want to block function calling. Can I do it?

Sample code:

public class Foo
{
    public Foo()
    {
        Initialize();
    }

    private void Initialize()
    {
        //some code
    }
}

[TestFixture]
public class Test
{
    [Test]
    public void Test_Foo()
    {
        Foo foo = MockRepository.GenerateMock<Foo>(); 

        //some test
    }
}

Notes:

  1. I don't want to add interface, like Foo : IFoo.
  2. I don't want to add second constructor.
k.m
  • 30,794
  • 10
  • 62
  • 86
Rougher
  • 834
  • 5
  • 19
  • 46
  • 2
    You can't do that. You either need to add second constructor or delegate `.Initialize` to dependency and inject. What exactly are you testing? Testing mocked object makes little sense, I hope you know that. – k.m Apr 25 '12 at 12:07
  • You can create an instance of Foo without calling the constructor using `FormatterServices.GetUninitializedObject(...)` . See here for details : http://stackoverflow.com/questions/178645/how-does-wcf-deserialization-instantiate-objects-without-calling-a-constructor – JYL Feb 17 '15 at 13:57

3 Answers3

1

When you are mocking a class, there is proxy created (Rhino uses Castle.DynamicProxy.DefaultProxyBuilder), which inherits from your class. And inheritance works exactly like anywhere in C#. When you create instance of derived type, all constructors of base types (up to object) are invoked.

So, when instance of proxy is created (via Activator.CreateInstance(typeof(proxy))), constructor of Foo also will be invoked. You can't avoid this. You can use interface mocking, or provide some parameter to constructor which will disable initializing.

BTW mocking abstract or concrete class kills all advantages of mocks - your tests becomes dependent on something that is not mocked (constructors, non-virtual methods and default implementations). And your SUT (system under test) is not tested in isolation anymore. Broken test could be result of some changes inside abstract or concrete class.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

In general you can create mocks of interfaces or abstract classes only.

What are you going to test? If it is the class Foo then creating a mock of it is completely wrong.

Usually you create mocks of those dependencincies of your tested class that are hard to set up or take long to run. Most common example of such dependency is a repository or a web-service.

Ivan Gerken
  • 914
  • 1
  • 9
  • 21
  • You are write. It's simple example, but this example shows my problem. Let's take Foo like abstract class. – Rougher Apr 25 '12 at 09:55
  • Anyway, if you test Foo then creating a mock of if is the wrong approach. – Ivan Gerken Apr 25 '12 at 10:23
  • @IvanGerken: *"you can create mocks of interfaces or abstract classes only"* - this is not true; Rhino can mock normal class just as well, there's nothing special about that. If the class exposes virtual methods, then those methods can be mocked just as if it was an interface. – k.m Apr 25 '12 at 12:09
  • @immy_keen You are right. I meant that in most cases it makes sense to create mock implementations of interfaces or abstract classes only. In my opinion the need of creating a mock of a concrete class is a bad smell. – Ivan Gerken Apr 26 '12 at 07:01
0

How abt adding a Boolean flag

Boolean flag = false;

[Test]

public void Test_Foo()
{
     if(flag == true)
     {
      Foo foo = MockRepository.GenerateMock<Foo>(); 

     }
    //some test
}
Sats
  • 1,913
  • 1
  • 15
  • 21