This is a migrated thread and some comments may be shown as answers.

Mocking base class with ctor

7 Answers 478 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Anthony
Top achievements
Rank 1
Anthony asked on 08 Aug 2012, 03:21 AM
I have a simple scenario.  I'm trying to mock a base class that creates a Guid and sets that to a property in the ctor.  I thought I could do that with the following code; however, the mocked object is not calling the ctor.  The result is that my property is Guid.Empty and my unit test fails.

What do I need to do to make this work?  In the meantime, I've just created a concrete class to make my test pass.  However, I'd rather get away from that and use JustMock.

var source = Mock.Create<FooBase>(Constructor.Mocked);

7 Answers, 1 is accepted

Sort by
0
Ricky
Telerik team
answered on 10 Aug 2012, 03:56 PM
Hi Anthony,

Thanks again for contacting us.  The mocked object should not be calling ctor since you have used Constructor.Mocked. 

Therefore, your syntax should be something like:


var source = Mock.Create<FooBase>(#your arguments#);

 

Kind Regards
Ricky
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Anthony
Top achievements
Rank 1
answered on 11 Aug 2012, 04:30 PM
Ricky,

The problem is that my constructor doesn't have parameters.  But knowing that I had the logic backwards led me to this.  It works, but I imagine it wouldn't be a good option if I was doing a more complex mock.

I'd appreciate if you'd let me know if there is a better way.

var source = Mock.Create<EventBase>(Constructor.NotMocked, Behavior.CallOriginal);
0
Ricky
Telerik team
answered on 14 Aug 2012, 05:23 PM
Hi Anthony,

Thanks again for contacting us. Generally, if you don't mention Constructor.Mocked then by default it will always call the original constructor. This is more or less similar to all mocking tools and also by default the mock will act as a stub therefore unless you specify Behavior.CallOriginal it should not call the original methods.

In case you want to pass the GUID to the mock object constructor, you can write this:

var foo = Mock.Create<Foo>(() => new Foo(Guid.NewGuid()));


Hope this answers your question.

P.S. On August 23rd, we are doing a JustMock webinar with Chris Eargle (Just Evangelist and C# MVP), please feel free to join and share your valuable insights that might help us align the product better.

Here goes the link to signup:
https://www1.gotomeeting.com/register/210978177


Kind Regards
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Anthony
Top achievements
Rank 1
answered on 14 Aug 2012, 05:35 PM
Thank you for the reply, but your suggestions don't apply to my scenario (see original).  Here's a summary:
  • I'm mocking a base class, so there's no ctor to call directly
  • My ctor doesn't have parameters, the Guid is created in the body of the ctor
0
Ricky
Telerik team
answered on 18 Aug 2012, 03:02 AM
Hi Anthony,

Thanks again for your reply. 

However, even you are mocking a base class that has a default constructor or constructor with no parameter unless you are specifying Constructor.Mocked it should be called.  Also, I would request you to send us a sample of the scenario that does not work for you so that we can investigate further and provide you with a better solution or alternative.

In addition, we will also check if mocking an abstract class raises the issue where the default constructor is never been called if mocked.


Kind Regards
Ricky
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Anthony
Top achievements
Rank 1
answered on 20 Aug 2012, 11:38 PM
I'll run through the code for the sake of having it all documented in case someone else runs into the same problem.  I can send a test project if you want, but I cannot attach it to this post.

Define my base class with the side effect in the ctor.
public abstract class BaseObject {
    protected BaseObject() {
        Id = Guid.NewGuid();
    }
 
    public Guid Id { get; private set; }
}

Now, define the test to ensure the Id property is set when a concrete object is created.  I create a test project, a test class, and then define the test.  This is where I use JustMock.
[TestMethod]
public void IdAssignedInCtor() {
    var source = Mock.Create<BaseObject>();
    var notExpected = Guid.Empty;
 
    var actual = source.Id;     // ctor not called if this is Guid.Empty
    Assert.AreNotEqual(notExpected, actual);
}

This fails when the test runs.  The Id property is not set, because the ctor is not called.  But, if I use a different overload it works.
[TestMethod]
public void IdAssignedInCtorAlt() {
    var source = Mock.Create<BaseObject>(Constructor.NotMocked, Behavior.CallOriginal);
    var notExpected = Guid.Empty;
 
    var actual = source.Id;
    Assert.AreNotEqual(notExpected, actual);
}


0
Ricky
Telerik team
answered on 23 Aug 2012, 08:31 PM
Hi Anthony,

Thanks again for providing the sample. 

However this will work if you just apply Behavior.CallOriginal on the Id property. By default when you create a mock, it acts as a stub therefore it won’t invoke the original getter method of the property and will return Guid.Empty, but it as expected calls the constructor.



[Test]
public void IdAssignedInCtor()
{
    var source = Mock.Create<BaseObject>();
    var notExpected = Guid.Empty;
 
    Mock.Arrange(() => source.Id).CallOriginal();
 
    var actual = source.Id;   // this will pass
    Assert.AreNotEqual(notExpected, actual);
}


Hope this answers your question.
 
Kind Regards
Ricky
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
General Discussions
Asked by
Anthony
Top achievements
Rank 1
Answers by
Ricky
Telerik team
Anthony
Top achievements
Rank 1
Share this question
or