I have an interface which I am mocking with 'NSubstitute' which contains properties that return concreate classes, that is the return value is not an interface. e.g
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
The 'SomeObj' concrete class has a default constructor but 'NSubstitute' always returns 'null' for these properties. The class itself is not under my control so I cannot simply make it derive from an interface.
Can 'NSubstitute' mock these type of properties? Or is there a way to override the behaviour? Otherwise I have to manually initialise the mock before the test and that can be a lot of code (even if its reused through a common method).
Perhaps there is a simpler solution that I have over-looked?
Classes will be auto-mocked if they have a default (parameterless) constructor and all its members are virtual (see the note in the intro of Auto and recursive mocks). The aim of this is to reduce the potential for unwanted (destructive?) side-effects if we are using a substitute and suddenly hit a non-virtual, unmocked code path that does bad stuff in an instance we thought was fake.
NSubstitute doesn't have a way override this behaviour. Instead, I'd recommend creating all your substitutes via your own factory method (e.g. a static Sub.For<T>(...) method in your test project) that uses NSubstitute to produce a substitute, then applies all the specific initialisation rules you need, like using reflection to stub out values for each class property.
Hope this helps.
Possibly related links:
I advise trying to avoid mocking types we don't own.
Stack Overflow: Is it recommended to mock concrete class?
Hacky factory method sample that subs properties using reflection.
It doesn't count as auto-mocking but you did also ask "Or is there a way to override the behaviour?" and "Perhaps there is a simpler solution that I have over-looked?"
This answer relies on the statements in your question that:
SomeObj is a class outside of your control, from which I assume it is either separately tested or else not testable
SomeObj has a default constructor
Sure, it requires you to "manually initialise the mock before the test" but since you've not told us what this object is it's not possible to know how much work it would take to implement fully.
public class SomeObj
{
// Non-virtual to prevent auto-mocking
public void Dummy() { }
}
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
[TestMethod]
public void Test_17182355ms()
{
ISomething mockedSomething = Substitute.For<ISomething>();
SomeObj firstObj = mockedSomething.First;
Assert.IsNull(firstObj);
mockedSomething.First.Returns(new SomeObj());
mockedSomething.Second.Returns(new SomeObj());
firstObj = mockedSomething.First;
Assert.IsNotNull(firstObj);
}
Another approach, though not without its own drawbacks, would be to extract your own interface for SomeObj, something like this:
public interface ISomeObj
{
void Dummy();
}
public class MySomeObj : SomeObj, ISomeObj
{
}
and then mock ISomeObj in your test.
Related
C# 8 supports default method implementations in interfaces. My idea was to inject a logging method into classes like this:
public interface ILoggable {
void Log(string message) => DoSomethingWith(message);
}
public class MyClass : ILoggable {
void MyMethod() {
Log("Using injected logging"); // COMPILER ERROR
}
}
I get a compiler error: "The name does not exist in the current context"
Is it impossible to use default method implementations in this way?
EDIT:
For the correct response regarding C# rules, see the accepted answer. For a more concise solution (the original idea of my question!) see my own answer below.
See the documentation at https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/default-interface-members-versions
That cast from SampleCustomer to ICustomer is necessary. The SampleCustomer class doesn't need to provide an implementation for ComputeLoyaltyDiscount; that's provided by the ICustomer interface. However, the SampleCustomer class doesn't inherit members from its interfaces. That rule hasn't changed. In order to call any method declared and implemented in the interface, the variable must be the type of the interface, ICustomer in this example.
So the method is something like
public class MyClass : ILoggable {
void MyMethod() {
ILoggable loggable = this;
loggable.Log("Using injected logging");
}
}
If you want to avoid clutter and repetitive casting you can add a single property which casts the type as the interface:
public class MyClass : ILoggable
{
ILoggable AsILoggable => (ILoggable)this;
void MyMethod()
{
AsILoggable.Log("Using injected logging");
}
}
But this is off. It seems wrong, regardless of how it's done. From the documentation:
The most common scenario is to safely add members to an interface already released and used by innumerable clients.
When there was some concern about having implementations in interfaces - which previously had none - this was the sentence that made sense of it. It's a way to add to an interface without breaking classes that already implement it.
But this question implies that we are modifying the class to reflect a change to an interface it implements. It's the exact opposite of the stated use case for this language feature.
If we're already modifying the class, why not just implement the method?
public void Log(string message) => DoSomethingWith(message);
When we add a default interface implementation, we provide an implementation to consumers of the interface - classes that depend on an abstraction.
If we depend on the default interface implementation from within the class that implements the interface, then a change to the interface becomes, in effect, a change to the internal implementation of the class. That's not what an interface is for. An interface represents external-facing behavior, not internal implementation.
It's as if the class is stepping outside of itself, looking back in at itself as an external consumer, and using that as part of its internal implementation. The class doesn't implement the interface, but it depends on it. That's weird.
I won't go so far as to say that it's wrong, but it feels like an abuse of the feature.
In CLR all interface member implementations are explicit, so in your code Log will be available in instances of ILoggable only, like it's recommended to do here:
((ILoggable)this).Log("Using injected logging")
The problem with the answers that cast the class to an interface is that it may or may not call the default interface method, depending on whether or not the class has implemented a method to override the default method.
So this code:
((ILoggable)this).Log(...)
ends up calling the default interface method, but only if there is no interface method defined in the class that overrides the default method.
If there is a method in the class that overrides the default method, then that is the method that will be called. This is usually the desired behavior. But, if you always want to call the default method, regardless of whether or not the implementing class has implemented its own version of that interface method, then you have a couple of options. One way is to:
Declare the default method as static. Don't worry, you will still be able to override it in a class that inherits from it.
Call the default method using the same type of syntax when calling a static method of a class, only substitute the interface name for the class name.
See this answer for a code example, along with an alternative way of calling a default interface method.
From reading an article about these default methods, I think you should try to upcast it to the interface:
((ILoggable)this).Log("Using injected logging")
I haven't checked it, just my thought according to this article.
Here are two alternative solutions to the ones already suggested:
First is to simply implement the interface method:
public class MyClass : ILoggable {
void MyMethod() {
Log("Using injected logging");
}
public void Log(string message) => ((ILog)this).Log(message);
}
This allows the method to be called directly, without having to write the cast to ILog each time.
Things to note:
this will make the method available on MyClass to outside users of it as well, where previously it was only available when an instance of MyClass is cast to / used as ILog
if you want to use 10 different methods from ILog in your class, you probably don't want to implement them all.
on the flipside, there are many scenarios where this is the "natural" / intended approach, primarily when MyClass extends the interface method with some custom logic (like ((ILog)this).Log("(MyClass): " + message) )
Second is using extension methods:
public static class LogExtensions
{
public static void Log<T>(this T logger, string message) where T : ILoggable => logger.Log(message);
}
public class MyClass : ILoggable {
void MyMethod() {
this.Log("Using injected logging");
}
}
This might be useful when ILoggable contains many methods / is implemented in many classes.
this still allows for Log to be overwritten in MyClass and the override to be called
essentially just syntactic sugar, shortening ((ILoggable)this) to this
The accepted answer and the other responses are correct.
However, what I wanted is a concise call of the Log method.
I achieved that with an extension method on the ILoggable interface:
public static class ILoggableUtils { // For extension methods on ILoggable
public static void Log(this ILoggable instance, string message) {
DoSomethingWith(message, instance.SomePropertyOfILoggable);
}
}
In this way, I can at least call this.Log(...); in my class instead of the ugly ((ILoggable)this).Log(...).
My solution is adding new abstract class between interface and it's implementations:
public interface ILoggable {
void Log(string message);
void SomeOtherInterfaceMethod();
}
public abstract class Loggable : ILoggable {
void Log(string message) => DoSomethingWith(message);
public abstract void SomeOtherInterfaceMethod(); // Still not implemented
}
public class MyClass : Loggable {
void MyMethod() {
Log("Using injected logging"); // No ERROR
}
public override void SomeOtherInterfaceMethod(){ // override modifier needed
// implementation
};
}
It came to my attention lately that you can unit test abstract base classes using Moq rather than creating a dummy class in test that implements the abstract base class. See How to use moq to test a concrete method in an abstract class? E.g. you can do:
public abstract class MyAbstractClass
{
public virtual void MyMethod()
{
// ...
}
}
[Test]
public void MyMethodTest()
{
// Arrange
Mock<MyAbstractClass> mock = new Mock<MyAbstractClass>() { CallBase = true };
// Act
mock.Object.MyMethod();
// Assert
// ...
}
Now I was wondering if there was a similar technique to allow me to test protected members without having to create a wrapper class. I.e. how do you test this method:
public class MyClassWithProtectedMethod
{
protected void MyProtectedMethod()
{
}
}
I'm aware of the Moq.Protected namespace, however as far as I can see it only allows you to setup expectations with e.g.
mock.Protected().Setup("MyProtectedMethod").Verifiable();
I'm also aware that the obvious answer here is "don't test protected methods, only test public methods", however that's another debate! I just want to know if this is possible using Moq.
Update: below is how I would test this normally:
public class MyClassWithProtectedMethodTester : MyClassWithProtectedMethod
{
public void MyProtectedMethod()
{
base.MyProtectedMethod();
}
}
Thanks in advance.
Another way in Moq to call protected member is the following template:
In your class, with protected member mark your function as virtual.
For example:
public class ClassProtected
{
public string CallingFunction(Customer customer)
{
var firstName = ProtectedFunction(customer.FirstName);
var lastName = ProtectedFunction(customer.LastName);
return string.Format("{0}, {1}", lastName, firstName);
}
protected virtual string ProtectedFunction(string value)
{
return value.Replace("SAP", string.Empty);
}
}
Then in your unit test add reference to
using Moq.Protected;
and in your unit test you can write the following:
[TestFixture]
public class TestClassProttected
{
[Test]
public void all_bad_words_should_be_scrubbed()
{
//Arrange
var mockCustomerNameFormatter = new Mock<ClassProtected>();
mockCustomerNameFormatter.Protected()
.Setup<string>("ProtectedFunction", ItExpr.IsAny<string>())
.Returns("here can be any value")
.Verifiable(); // you should call this function in any case. Without calling next Verify will not give you any benefit at all
//Act
mockCustomerNameFormatter.Object.CallingFunction(new Customer());
//Assert
mockCustomerNameFormatter.Verify();
}
}
Take note of ItExpr. It should be used instead of It. Another gotcha awaits you at Verifiable. I don't know why, but without calling to Verifiable Verify will not be called.
For starters, there's no point in unit testing an abstract method. There's no implementation! You may want to unit test an impure abstract class, verifying that the abstract method was called:
[Test]
public void Do_WhenCalled_CallsMyAbstractMethod()
{
var sutMock = new Mock<MyAbstractClass>() { CallBase = true };
sutMock.Object.Do();
sutMock.Verify(x => x.MyAbstractMethod());
}
public abstract class MyAbstractClass
{
public void Do()
{
MyAbstractMethod();
}
public abstract void MyAbstractMethod();
}
Note that I set CallBase to turn this into a partial mock, in case Do was virtual. Otherwise Moq would have replaced the implementation of the Do method.
Using Protected() you could verify that a protected method was called in a similar manner.
When you create a mock with Moq or another library, the whole point is overriding implementation. Testing a protected method involves exposing existing implementation. That's not what Moq is designed to do. Protected() just gives you access (presumably through reflection, since it's string-based) to override protected members.
Either write a test descendant class with a method that calls your protected method, or use reflection in the unit test to call the protected method.
Or, better yet, don't test protected methods directly.
You've already touched upon the "test the public API, not private" thought process, and you've also already mentioned the technique of inheriting from the class and then testing its protected members that way. Both of these are valid approaches.
Beneath it all, the simple truth is that you consider this implementation detail (as that's what a private or protected member is) important enough to test directly rather than indirectly via the public API that would use it. If it is this important, perhaps it's important enough to promote to its own class. (After all, if it's so important, perhaps it is a responsibility that MyAbstractClass should not have.) The instance of the class would be protected inside MyAbstractClass, so only the base and derived types would have access to the instance, but the class itself would be fully testable otherwise and usable elsewhere if that became a need.
abstract class MyAbstractClass
{
protected ImportantMethodDoer doer;
}
class ImportantMethodDoer
{
public void Do() { }
}
Otherwise, you're left* to the approaches you've already identified.
*Moq may or may not provide some mechanism for getting at private or protected members, I cannot say, as I do not use that particular tool. My answer is more from an architectural standpoint.
Doesn't being required to virtualize all property accessors you want to mock kind of defeat the purpose of mocking?
I mean, if I have to modify my object and virtualize every single accesor I want to mock, couldn't I just as well inherit my class and mock it myself?
Your question is very valid but if you think about it,there is no other way to mock a class. If you take an interface, it's just a contract so the mock framework can mock how ever you want it but if you take a class, it already has an implementation for it's members.
So the mock framework, in order to be able to mock the class members, has to inherit from the class and override the member's behavior as requested and for this purpose only virtual members will work.
For eg. if you have (I'm showing methods but the same is true for properties)
class Foo
{
public void Bar()
{
}
public virtual void virtualBar()
{
}
}
then the mock framework probably creates something like this to mock
public class MockFoo : Foo
{
public override void virtualBar()
{
// mockery action
}
public new void Bar()
{
// mockery action
}
}
Now when you have
Foo foo = GetMockObject(); // you get an instance of MockFoo
now when you call
foo.Bar();
you don't intend for it to call the actual implementation but since it's a non virtual member, it will call the Foo's Bar()
on the other hand, calling
foo.VirtualBar();
would call MockFoo's VirtualBar() as it's a virtual member which would have the behavior injected by the mock framework as requested.
If I'm mocking a class, like below, is there any way I can get the mock to not override a virtual method? I know I can simply remove the virtual modifier, but I actually want to stub out behavior for this method later.
In other words, how can I get this test to pass, other than removing the virtual modifier:
namespace Sandbox {
public class classToMock {
public int IntProperty { get; set; }
public virtual void DoIt() {
IntProperty = 1;
}
}
public class Foo {
static void Main(string[] args) {
classToMock c = MockRepository.GenerateMock<classToMock>();
c.DoIt();
Assert.AreEqual(1, c.IntProperty);
Console.WriteLine("Pass");
}
}
}
You want to use a partial mock, which will only override the method when you create an expectation:
classToMock c = MockRepository.GeneratePartialMock<classToMock>();
c.DoIt();
Assert.AreEqual(1, c.IntProperty);
I see a couple of things here.
First, you are mocking a concrete class. In most/all cases, this is a bad idea, and usually indicates a flaw in your design (IMHO). If possible, extract an interface and mock that.
Second, although technically the mock is overriding the virtual method, it might be better to think of what it is doing is actually mocking/faking the method by providing an implementation (one that does nothing in this case). In general, when you mock an object, you need to provide the implementation for each property or method your test case requires of the object.
Update: also, I think removing "virtual" will prevent the framework from being able to do anything with the method.
I ended up with something like the following code in a project I'm working on. I thought it was really odd that I was allowed to do it, but now I'm starting wonder what is most likely an architectural gaff on my part led me to this.
My questions to you are:
What exactly is this called?
What are some real world uses of this?
Why would anyone want to do this?
Here are my Interfaces:
namespace ThisAndThat
{
public interface ICanDoThis
{
string Do();
}
public interface ICanDoThat
{
string Do();
}
public interface ICanDoThisAndThat : ICanDoThis, ICanDoThat
{
new string Do();
}
}
Here's my concrete class:
namespace ThisAndThat
{
public class CanDoThisAndThat : ICanDoThisAndThat
{
public string Do()
{
return "I Can Do This And That!";
}
string ICanDoThis.Do()
{
return "I Can Do This!";
}
string ICanDoThat.Do()
{
return "I Can Do That!";
}
}
}
And my passing tests:
using Xunit;
namespace ThisAndThat.Tests
{
public class ThisAndThatTests
{
[Fact]
public void I_Can_Do_This_And_That()
{
ICanDoThisAndThat sut = new CanDoThisAndThat();
Assert.Equal("I Can Do This And That!", sut.Do());
}
[Fact]
public void I_Can_Do_This()
{
ICanDoThis sut = new CanDoThisAndThat();
Assert.Equal("I Can Do This!", sut.Do());
}
[Fact]
public void I_Can_Do_That()
{
ICanDoThat sut = new CanDoThisAndThat();
Assert.Equal("I Can Do That!", sut.Do());
}
}
}
There is absolutely nothing wrong with this code (provided it isn't confusing for your users), and it isn't a pattern with any name that I'm familiar with. CanDoThisAndThat implements two interfaces, so clients can use it in either way.
.NET allows interfaces to be implemented this way -- known as explicit interface implementation.
Explicit interface implementation is useful when:
Two interfaces have the same member definition
You need to implement an interface but don't want to publicise that a particular member is available to client code that has not declared a reference using the interface type
An example of case 2 from the .NET framework is ICollection.SyncLock. List<T> implements ICollection yet the following code will not compile because the member has intentionally been 'hidden' as the designers of the BCL no longer advocate locking collections in this way:
List<object> list = new List<object>();
lock (list.SyncRoot) // compiler fails here
{
// ...
}
Any legacy code of this format will still work, because the reference is of type ICollection explicitly:
ICollection list = new List<object>();
lock (list.SyncRoot) // no problem
{
// ...
}
Each type has an interface mapping (which can be retrieved with Type.GetInterfaceMap if you want to look at it with reflection). This basically says, "When method X on interface Y is invoked, this method Z is the one to call." Note that even though it's not supported in C#, it's possible for the mapping target method to have a different name from the interface method name! (VB explicitly supports this, I believe.)
In your case, you have three methods and each of the three methods corresponds to a method in one of the interfaces involved.
When the compiler issues a call to a virtual method via an interface, the IL generated says something like "call IFoo.Bar on this object" - and IFoo.Bar is then resolved using the interface map.
You may sometimes need to use it if either you have signatures which differ only in return type, or if you're implementing two heterogeneous interfaces which happen to have the same method names but should do different things. Wherever you can avoid it though, do! It makes for very confusing code.