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.
Related
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. :)
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
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.
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.
When I'm in need to mock some class that goes like this:
public class Dummy
{
private readonly int _someInt;
private readonly int _someOtherInt;
private readonly IFoo _foo;
public Dummy(int someInt,int someOtherInt, IFoo foo)
{
_someInt = someInt;
_someOtherInt = someOtherInt;
_foo = foo;
}
}
I use Moq to do something like this:
[Test]
public void ShouldCreateADummyInstance()
{
var someInt = 1;
var someOtherInt = 2;
var mockFoo = new Mock<IFoo>();
var dummy = new Dummy(someInt, someOtherInt, mockFoo.Object);
//And so on...
}
But when I use AutoMoq I can't specify a different int for each dependency (I mean someInt and someOtherInt) into my constructor because AutoMoqer.SetInstace(instanceIWantToUse) sets the same specified instance each time that has to supply that dependecy.
Do you know how can I specify a different int for someInt and someOtherInt in order to keep using AutoMoqer in my tests ?
Thanks, hope you can help me out!
Full disclosure: I've never used AutoMoq (though I did just sign up to follow it on GitHub since it looks intriguing and I like things that cut down on boilerplate).
That said, it looks like the AutoMoq tool was designed for a different use case than yours. It appears that he uses it to "future proof" against broken unit tests if another constructor injected dependency is added, and to be able to generate a default object with something there for the dependencies, presumably to avoid null reference exceptions.
I would assume after reading the AutoMoq project page that if Darren were writing your particular unit test, he would probably just use Moq out of the box. That is, for that particular test, you should probably go with the test that you have posted. AutoMoq appears to aim at supplying sensible default behavior for when you don't want to bother specifying all of your dependencies in a test. But in your case, you do want to specify those particular dependencies.
Just because you use regular Moq for that particular test doesn't mean that you can't use AutoMoq for other tests. The rest of your tests (where both ints are zero or whatever) will be future-proofed, but you may just have to live with that one breaking if you add another constructor parameter to your Dummy class.
(You could also always snag the source code for AutoMoq and modify it to your needs).
Solution similar to Moq
You can create an instance of Dummy in AutoMoq very similar as you do in Moq.
This does not future proof your testcode against changes in the constructor parameters, but may still be acceptable.
var mocker = new AutoMoqer();
var fooMock = mocker.GetMock<IFoo>();
var dummy = new Dummy(1, 2, fooMock.Object);
// test something about dummy
Solution with AutoMoq
If you really want to future proof your TestCode, then it may be neccessary to change the constructor to depend on interfaces.
interface IDummyParameters {
int SomeInt {get;set;}
int SomeOtherInt {get;set;}
}
public class Dummy {
public Dummy(IDummyParameters parameters, IFoo foo){
...
}
}
Then you can create your Dummy class with AutoMoq like this:
var mocker = new AutoMoqer();
mocker.GetMock<IDummyParameters>.Setup(x => x.SomeInt).Returns(1);
mocker.GetMock<IDummyParameters>.Setup(x => x.SomeOtherInt).Returns(2);
// notice how this code does not say anything about IFoo.
// It is created automatically by AutoMoq
var dummy = mocker.Create<Dummy>();