My method needs to be virtual?

1,213 views
Skip to first unread message

Philippe Lavoie

unread,
Apr 28, 2008, 12:58:11 PM4/28/08
to moq...@googlegroups.com
Hi

Do I really need to mark my methods as virtual if I want to mock them with moq?

I'd like the following two tests to work. What is the work around?

public class Foo
{
public void Bar()
{
}

public virtual void Bar2()
{
}
}

/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1
{
[TestMethod]
public void ThisWorks()
{
bool called = false;
Mock<Foo> fooMock = new Mock<Foo>();
fooMock.Expect(foo => foo.Bar2()).Callback( () => called = true);
fooMock.Object.Bar2();
Assert.AreEqual(true,called);
}

[TestMethod]
public void ThisDoesnt()
{
bool called = false;
Mock<Foo> fooMock = new Mock<Foo>();
fooMock.Expect(foo => foo.Bar()).Callback( () => called = true);
fooMock.Object.Bar();
Assert.AreEqual(true,called);
}
}

Thanks

Phil

PS Please include my e-mail in the response.

Nathan Stott

unread,
Apr 28, 2008, 1:00:49 PM4/28/08
to moq...@googlegroups.com
Yes you really need to mark them virtual. Dynamic Proxy can not
intercept method calls to non virtual, non abstract methods.

Daniel Cazzulino

unread,
Apr 28, 2008, 6:30:49 PM4/28/08
to moq...@googlegroups.com
a "workaround" would be to define an interface for your object, and mock the interface rather than the actual implementation (which may be a smell in itself...)

philipp...@gmail.com

unread,
Apr 29, 2008, 10:09:21 AM4/29/08
to MoQ Discussions
Thanks

Is this a limitation in the framework or in .Net 3.5 ?


Phil

Daniel Cazzulino

unread,
Apr 29, 2008, 12:10:51 PM4/29/08
to moq...@googlegroups.com
it's a limitation of the CLR since its inception: there's no built-in interception mechanism.

so, the interception mechanism we use is auto-generated classes that inherit from the types to mock, and override all members to provide the interception. that's why they need to be virtual.

we're reusing the interception library from Castle DynamicProxy for doing that.

philipp...@gmail.com

unread,
Apr 29, 2008, 10:11:42 PM4/29/08
to MoQ Discussions

Thanks for the clarification. I guess we just have to hope that the
powers that be decide to change this in .Net 4.0.

Regards

Phil

Daniel Cazzulino

unread,
Sep 30, 2008, 8:23:23 AM9/30/08
to moq...@googlegroups.com
To me, it's no smell.

Some may argue that being "forced" (you can always just mark the
member virtual and that's it) to create an interface just for mock-
ability rather than architecture/design decision is a smell...


Sent from my iPod

On Sep 29, 2008, at 9:16 PM, panjkov <dp....@gmail.com> wrote:

> why is this a smell?
>
> Interface:
> public interface IPhotosRepository {
>
> IList<Album> Albums();
> ...
> }
>
> Repository:
> public class PhotosRepository : IPhotosRepository {
> #region IPhotosRepository Members
>
> public IList<Album> Albums() {
> List<Album> albums = new List<Album>();
> return albums;
> }
> ...
>
> Unit test:
> public void Albums_ShouldReturnListOfAlbums() {
> // Arrange
> var albums = new List<Album>();
> albums.Add(...});
> albums.Add(...);
>
> var repository = new Mock<IPhotosRepository>();
> repository.Expect(r => r.Albums()).Returns(albums);
>
>
> // Act
> PhotosController controller = new PhotosController();
> ViewResult result = controller.Albums() as ViewResult;
>
> // Assert
> Assert.IsNotNull(result, "Expected the result to be a
> ViewResult");
>
> }
>
> This is first iteration. DB Code is not created at all, no dbml file,
> nothing. Any links or clarifications should be highly helpful /
> appreciated.


>
>
> On Apr 29, 12:30 am, "Daniel Cazzulino" <dan...@cazzulino.com> wrote:
>> a "workaround" would be to define an interface for your object, and
>> mock the
>> interface rather than the actual implementation (which may be a
>> smell in
>> itself...)
>>

>> On Mon, Apr 28, 2008 at 2:00 PM, Nathan Stott <nrst...@gmail.com>

Reply all
Reply to author
Forward
0 new messages