views:

49

answers:

4

It is necessary to check implementation of 'MyMethod' virtual method in the abstract 'MyAbstractClass':

public abstract MyAbstractClass
{
    public void MyMethod()
    {
        Testpassed = true;
    }

    public abstract int StatusCode{get;internal set;} // **EDIT**: internal setter was added

    public bool TestPassed{get;private set;}
}

I've tried to do the following:

[TestMethod()]
{
    Mock<MyAbstractClass> mockClass = new Mock<MyAbstractClass>();
    mockClass.Object.MyMethod();
    Assert.IsTrue(mockClass.Object.TestPassed);
}

on attempt to execute 'MyMethod' the following error is generated:

Method 'set_StatusCode' in type 'MyAbstractClass`2Proxy0434d60c0f4542fb9b4667ead4ca3a18' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation..

Please advise, how could I get the problem resolved?

Thanks a lot!

P.S. Actually, I could inherit from MyAbstractClass and provide implementation for 'StatusCode' property, but I have a bunch of properties to be implemented...

+1  A: 

I understand that it's not an answer to your moq question, but anyway. Even if you have a lot of abstract properties, VS makes it extremely easy to add empty (actually, throwing) implementations. So, if MyMethod does not depend on these properties by design, I'd add an empty derived class and test it.

Dmitry Ornatsky
Probably that is a good idea. But for this case if class interface is changed I will need to update interface of 'test' class, that is not really required...
Budda
A: 

See this answer about partial mocking and I think you'll have to provide a concrete implementation.

Preet Sangha
In linked answer I see the following: Partial mocking is only useful when you want to test the functionality of an abstract class with mocked implementations of abstract methods. That is what exactly required for me. The problem is: I don't know how to get that...
Budda
+2  A: 

The code that you posted runs fine (except for minor misspellings). I simply could not get it to fail with the same error. Moq implements the abstract property at runtime and makes it return the default value(0 in this case). Try a more recent version of Moq.

I would also caution against putting test logic into the class. If the only purpose of TestPassed is for testing than it definitely doesn't belong there. We could help a great deal more if you post real code.

Igor Zevaka
Thank you. 'TestPass' is for demo purpose only. :) You right, original example is working fine... Sorry for my fault, I didn't check it (it was simplified from my example). Now I see that problem is occurred for mocking 'internal' members... will try to resolve that.Thanks again!
Budda
Moq uses Castle Dynamic Proxy for creating mocks at runtime. If you are having problems with internal members, it's because dynamic proxy can't create those. You can add InternalsVisibleTo to the assembly containing SUT and specify Castle Dynamic Proxy in the argument to make it all work.
Igor Zevaka
I've tried to mark my assembly with InternalsVisibleTo, but it didn't help. Should it? Probably id did that an wrong way (only for one project... not for each project in assembly)...
Budda
The exception should be fairly explicit about what's not available to what. You will need to add `InternalsVisibleTo` to the assembly containing internal members and soecify Castle Dynamic Proxy in the argument. It will have to be full assembly name, with public key token and version.
Igor Zevaka
A: 

I see solution: change access modifier from "internal" to "protected internal"... But is it possible to make internal member visible to Moq?

Budda
Actually, I did so... after that class became mockable... but I don't really want to make these properties protected... I would like to find a way to make internal accessible for Moq. Ups. Commented own suggestion :)
Budda