Mock Unit Testing - Getting details of the classes implementing interface - c#

I have a User Interface lets call it IUser.
There are two implementations of this: AdminUser and NormalUser.
Now, I am trying to use these user classes via Unit Testing(Mocking).
I mock the interface as follows:
var mockUser = new Mock<IUser>();
mockUser.get("username");
I have added breakkpoints throughout the classes but I am not sure which instance of the interface is getting called i.e AdminUser or NormalUser.
It never stops at the debug points and no clue from the mockUser instance.
How can I get the details of the class being called by the mockUser mock instance?
Thanks in advance.

Creating a Mock<IUser> actually creates a new implementation of IUser. So it won't help you to test any of your actual implementations.
Using a Mock works something like this:
Suppose I have this class and interface. The class validates whether a postal code is valid for a country. It depends on another interface which provides the regex pattern for the given country.
public class PostalCodeValidator
{
private readonly IPostalCodeRegexProvider _regexProvider;
public PostalCodeValidator(IPostalCodeRegexProvider regexProvider)
{
_regexProvider = regexProvider;
}
public bool ValidatePostalCode(string postalCode, string countryCode)
{
var regex = _regexProvider.GetPostalCodeRegex(countryCode);
if (string.IsNullOrEmpty(regex)) return true;
return Regex.IsMatch(postalCode, regex);
}
}
public interface IPostalCodeRegexProvider
{
string GetPostalCodeRegex(string countryCode);
}
The implementation of IPostalCodeRegexProvider could be anything. It could call a database, it could be hard-coded.
But when I write unit tests for PostalCodeValidator, I explicitly don't want to test a real implementation of IPostalCodeRegexProvider. I want to make IPostalCodeValidator return exactly what I want so that I can make sure that PostalCodeValidator works. I'm only testing PostalCodeValidator.
If I want to test that ValidatePostalCode returns true when IPostalCodeRegexProvider.GetPostalCode returns null, then I need to make sure that it will return null. That's where the Mock comes in.
It allows me to easily create an implementation of IPostalCodeRegexProvider that will always return null, so I can test what ValidatePostalCode does with that null.
[TestMethod]
public void ValidatePostalCode_ReturnsTrueWhenRegexIsNull()
{
var mock = new Mock<IPostalCodeRegexProvider>();
mock.Setup(x => x.GetPostalCodeRegex(It.IsAny<string>())).Returns(default(string));
var subject = new PostalCodeValidator(mock.Object);
Assert.IsTrue(subject.ValidatePostalCode("xyz","abc"));
}
Whatever the subject of the test is - in this case PostalCodeValidator, or in your case AdminUser and NormalUser - that's what you would create an instance of. If those classes depend on other interfaces then you might create a Mock for each of those interfaces.
You can also consider using a "test double." Instead of using Moq, you just create a simple class that implements the interface. For example, what I did with Moq I could also do like this:
public class PostalCodeRegexProviderThatReturnsNull : IPostalCodeRegexProvider
{
public string GetPostalCodeRegex(string countryCode)
{
return null;
}
}
Now the unit test would look like this:
public void ValidatePostalCode_ReturnsTrueWhenRegexIsNull()
{
var regexProvider = new PostalCodeRegexProviderThatReturnsNull();
var subject = new PostalCodeValidator(regexProvider);
Assert.IsTrue(subject.ValidatePostalCode("xyz","abc"));
}
That is often easier to understand than using a Mock. Sometimes the setup for mocks can get complicated and difficult to read and debug, but a simple class can do the job just as well or even better.

In order to test the actual implementations then you need to initialize the actual implementations i.e. new AdminUser().
For example
[TestMethod]
public void TestAdminUser {
//Arrange
IUser admin = new AdminUser();
//...set any necessary members relevant to the test
//Act
//...invoke member to be tested
//Assert
//...verify actual to expected behavior
}
If either of the implementations have external dependencies then you would mock those (the dependencies) and inject them.
If a class depended on an IUser
public class SomeClass {
private readonly IUser user;
public SomeClass(IUser user) {
this.user = user;
}
//...
}
and you wanted to test that class then you would have a reason to mock IUser for an isolated unit test.
[TestMethod]
public void TestSomeClass {
//Arrange
var username = "dummy";
var expected = "some value";
var mock = new Mock<IUser>();
//...set any necessary members relevant to the test
mock.Setup(_ => _.username).Returns(username);
var subject = new SomeClass(mock.Object);
//Act
//...invoke member to be tested
var actual = subject.SomeMethod();
//Assert
//...verify actual to expected behavior
Assert.AreEqual(actual, expected);
}
Reference Moq Quickstart to get a better understanding of how to use Moq

Related

NSubstitute ordered testing (Recived.InOrder) with return values for called methods results in CouldNotSetReturnDueToMissingInfoAboutLastCallException

I used to write my tests with RhinoMocks and have switched to NSubstitute.
Now I have a problem concerning ordered test.
Lets say I have three small classes like
public interface IProvider
{
int GetData();
}
public class Provider : IProvider
{
public int GetData()
{
return 3;
}
}
public interface ICalculator
{
int Calculate(int data);
}
public class Calculator : ICalculator
{
public int Calculate(int data)
{
if (data < 3)
{
return data;
}
return data * 2;
}
}
public class Operator
{
public void Operate(IProvider provider, ICalculator calculator)
{
int version = provider.GetData();
this.Result = calculator.Calculate(version);
}
public int Result
{
get;
private set;
}
}
When I write an ordered test using RhinoMocks, I can define the behaviour for the mocked classes like this:
[Test]
public void RhinoMockOrderedTest()
{
var mockRepository = new MockRepository();
var provider = mockRepository.DynamicMock<IProvider>();
var calculator = mockRepository.DynamicMock<ICalculator>();
using (mockRepository.Ordered())
{
provider.Expect(p => p.GetData()).Return(4);
calculator.Expect(c => c.Calculate(4)).Return(9);
}
mockRepository.ReplayAll();
var op = new Operator();
op.Operate(provider, calculator);
mockRepository.VerifyAll();
Assert.That(op.Result, Is.EqualTo(9));
}
Now I was trying to write an ordered test like the one above using NSubstitute, where I was also trying to check the call order and using defined return values:
[Test]
public void NSubstituteOrderedTest()
{
var provider = Substitute.For<IProvider>();
var calculator = Substitute.For<ICalculator>();
var op = new Operator();
op.Operate(provider, calculator);
Received.InOrder(() =>
{
provider.GetData().Returns(4);
calculator.Calculate(4).Returns(9);
});
Assert.That(op.Result, Is.EqualTo(9));
}
Unfortunalely this does not work. It seems to me, when I try to use .Returns for a methon inside of the Received.InOrder - Action, it will alwys fail like this:
NSubstitute.Exceptions.CouldNotSetReturnDueToMissingInfoAboutLastCallException
: Could not find information about the last call to return from.
Make sure you called Returns() after calling your substitute (for
example: mySub.SomeMethod().Returns(value)), and that you are not
configuring other substitutes within Returns() (for example, avoid
this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that
the call to your substitute was on a virtual/abstract member. Return
values cannot be configured for non-virtual/non-abstract members.
Correct use: mySub.SomeMethod().Returns(returnValue);
Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub()); Instead try: var
returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);
How can I write this test using NSubstitute ?
Thanks,
Nico
NSubstitute works differently to Rhino Mocks here -- it only supports Arrange-Act-Assert (AAA) style tests. This means we need to stub out calls we're interested in (arrange), run the code we want to test (act), then assert the results are as expected (assert).
Received.InOrder is only for assertions, and works like NSubstitute's Received() method for each call. Returns arranges for a call to return a particular result. NSubstitute does not allow us to mix the two. We can't do sub.Received().Calculate().Returns(42), and it does not make sense to in AAA as there is little point in stubbing a return value after asserting we have already acted on the subject being tested and received all required calls.
Here is a passing version of the test from the question that separates the stubbing/arranging from the assertions:
[Test]
public void NSubstituteOrderedTest() {
// Arrange
var provider = Substitute.For<IProvider>();
var calculator = Substitute.For<ICalculator>();
provider.GetData().Returns(4);
calculator.Calculate(4).Returns(9);
// Act
var op = new Operator();
op.Operate(provider, calculator);
// Assert
Received.InOrder(() =>
{
provider.GetData();
calculator.Calculate(4);
});
Assert.That(op.Result, Is.EqualTo(9));
}
Aside: I know this is a simplified example, but I think it's worth noting that in many cases we can get away without testing the call ordering. For this simple case, we know GetData() is called first, as its value is passed to Calculate(), so the order is enforced via the data dependency. If the end result is correct, we know the call chain was correct. For more complicated cases we can use types for this (Connect() returns ConnectedDb, then Query(ConnectedDb db) ensures Connect() was called first.
Relying on knowledge of the implementation details of the code being tested (such as call ordering) can lead to brittle tests (i.e. they fail with small changes that should not affect the overall result), so it is best to avoid this where possible.
However, even with this disclaimer, it is sometimes useful to assert call order instead, so I hope this answer clears up this NSubstitute feature for you. :)

How to Setup a readonly property with Moq?

I am trying to unit test using Moq. Here is the example code:
public class ConcreteClass
{
private readonly FirstPropery firstProperty;
private readonly SecondProperty secondProperty;
public ConcreteClass(firstProperty, secondProperty)
{
this.firstProperty = firstProperty;
this.secondProperty = secondProperty;
}
}
[TestMethod]
var concreteClassMock = new Mock<ConcreteClass>() { CallBase = true };
In my test method, I want to set firstProperty to reference a real object FirstProperty object (created by a factory), and later use it to test another object's behavior. Is there any way to achieve that?
Usually, you wouldn’t mock private members since you are only mocking the public interface of something. A mock is thus completely independent of implementation details.
That being said, you can pass constructor arguments to the Mock constructor that will then be passed on to the target’s constructor:
new Mock<ConcreteClass>(firstProperty, secondProperty) {CallBase = true};
However, if your goal is to actually test the ConcreteClass, you should not create a mock of it. You should test the actual object. So mock its dependencies and pass those if necessary, but keep the object you want to test actually real. Otherwise, you might introduce and test behavior that comes from the mock instead of the object you are testing:
var firstMock = new Mock<FirstProperty>();
var secondMock = new Mock<FirstProperty>();
var obj = new ConcreteClass(firstMock.Object, secondMock.Object);
obj.DoSomething();
// assert stuff
A few remarks:
1- It could be easily achieve with an interface and a get method like this:
public interface IConcreteClass
{
FirstProperty FirstProperty { get; }
}
[Test]
public void TestCase()
{
var yourFirstPropertyImplementation = new FirstProperty();
var concreteClassMock = new Mock<IConcreteClass>();
concreteClassMock.Setup(o => o.FirstProperty).Returns(yourFirstPropertyImplementation);
}
2- Depending of your scenario, do you really need a Moq, why not just use the true implementation and use moq only at boundaries?
3- You should clarify what you want to test? If it's concrete class? or the properties? or some other classes? The test case I propose in 1 is valid only to test the interaction of concrete class with some other classes.

Moq is making method call and returning real data, and not the return data in Setup

I am trying to return a statically declared array of NWatchNativeNode[], but Moq seems to actually be calling the real method that goes to the gets the real system data. Is the Setup in the below incorrect?
I want to make sure that when
GetNodesInCriticalCondition() is called, criticalNodes1 is returned.
Unit Test Code
var criticalNodes1 = new NWatchNativeNode[]
{
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch",
"MyAlias",
12345
),
factory.CreateNativeNode(NWatchNodeType.NetworkSwitch,
"MySwitch2",
"MyAlias2",
54321
),
};
var mock = new Mock<NWatchCasModelStatusScheduleEntry>(_application);
mock.Setup(x => x.GetNodesInCriticalCondition()).Returns(criticalNodes1);
var nodes = mock.Object.GetNodesInCriticalCondition();
Assert.AreEqual(2, nodes.Length); // This should return true
The most likely reason that the Mock returns the real system data is that your method GetNodesInCriticalCondition() is not declared virtual.
In order for Moq to be able to setup the method calls, these methods have to be virtual, otherwise it cannot overwrite them and hence cannot intercept them, which results in the original method being called.
Edit:
If your method is internal, you have to give access to it to your Unit Test project and to Moq.
You can do this by adding
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] and
[assembly: InternalsVisibleTo("TestProjectNameSpace")]
to the AssemblyInfo.cs file of the project you are creating mocks for.
As per your request, here is a quick example of how to test with Moq.
Let us make some classes and interfaces to test to start with.
public interface IFoo
{
IEnumerable<int> GetFoos();
}
public class Foo : IFoo
{
public IEnumerable<int> GetFoos()
{
return Enumerable.Range(1, 10);
}
}
public class Bar
{
private readonly IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public IEnumerable<int> SquareFoos()
{
foreach(var item in foo.GetFoos())
{
yield return item * item;
}
}
}
Now, Bar has a dependency on the IFoo interface. Now we want to test the functionality of SquareFoos on the Bar class. This is our subject under test. What we want to mock is the IFoo interface passed to the constructor of Bar. This gives us the following unit test setup.
// Arrange
var mock = new Mock<IFoo>();
mock.Setup(m => m.GetFoos()).Returns(Enumerable.Range(1, 2));
var sut = new Bar(mock.Object);
// Act
var results = sut.SquareFoos().ToList();
// Assert
Assert.AreEqual(2, results.Count);
In this case we mock out what GetFoos returns to allow us to test our Bar class.

force relay to mocking framework

I would like to create a customization that configures AutoFixture to pass types it DOES have implementations for off to Moq instead. How can I do that generically?
To clarify, consider:
public class test
{
public string foo;
public test(IDictionary<string, string> stuffing)
{
foo = stuffing["bogus"];
}
}
[TestMethod]
public void testInjection()
{
var fixture = new Fixture();
bool didThrow;
try
{
var sut = fixture.Create<test>();
didThrow = false;
}
catch
{
didThrow = true;
}
Assert.IsTrue(didThrow);
}
The test passes. AutoFixture has provided me with a dummy collection compatible with IDictionary. I would like the test to fail... specifically, I'd like to hand the IDictionary off to Moq and get something that doesn't complain about missing keys by default.
I'd like to use something like fixture.UseAutoMoq().ForceRelay<Dictionary<string,string>>().
I'm also open to better suggestions... but consider the test class sealed. I'm testing into code that uses this pattern a lot and I want a test convention around it.
To do what you ask for, you can take the MockRelay added by AutoMoqCustomization and move it in front of the well-known-collections-builders:
[Fact]
public void PassByMovingAutoMoqRelay()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var relay = fixture.ResidueCollectors.OfType<MockRelay>().Single();
fixture.Customizations.Add(relay);
var sut = fixture.Create<MyClass>(); // Doesn't throw
}
However, I don't think it's a good idea, as most of the .NET collection interfaces are big fat LSP violations, and there's no guarantee that auto-mocking them will produce meaningful behaviours - I'd expect the opposite to be the case.

Testing StructureMap convention

I have a convention for StructureMap that looks like this:
public class FakeRepositoriesConvention : IRegistrationConvention
{
public void Process(Type type, global::StructureMap.Configuration.DSL.Registry registry)
{
if (type.Name.StartsWith("Fake") && type.Name.EndsWith("Repository"))
{
string interfaceName = "I" + type.Name.Replace("Fake", String.Empty);
registry.AddType(type.GetInterface(interfaceName), type);
}
}
}
I want to implement unit tests for this, but I don't know how to do that.
My first thought was to send in a mocked Registry and just test that AddType() is called with the right parameters. I can't get that to work though, probably because AddType() is not virtual. Registry implements IRegistry but that doesn't help me since the Process method doesn't accept an interface.
So my question is - how can I test this?
(I'm using nUnit and RhinoMocks)
You can skip mocking altogether and use simplified version of your registry and component with predefined dummy types:
// Dummy types for test usage only
public interface ICorrectRepository { }
public class FakeCorrectRepository : ICorrectRepository { }
[Test]
Process_RegistersFakeRepositoryType_ThroughInterfaceTypeName()
{
var registry = new Registry();
var convention = new FakeRepositoriesConvention();
// exercise test
convention.Process(typeof(FakeCorrectRepository), registry);
// assert it worked
var container = new Container(c => c.AddRegistry(registry));
var instance = container.GetInstance<ICorrectRepository>();
Assert.That(instance, Is.Not.Null);
}
If your convention works as you assume it does, test above should pass.

Categories

Resources