Mocking TransactionTemplate from Spring.Net with Rhino mocks - c#

I'm trying to create mock of TransactionTemplate
var tTemplate = MockRepository.GenerateMock<TransactionTemplate>();
var tDelegate = MockRepository.GenerateMock<ITransactionCallback>();
tTemplate.Expect(x => x.Execute(tDelegate)).IgnoreArguments().Throw(new Exception());
on last line i get NullPointerException from
at Spring.Transaction.Support.TransactionTemplate.Execute(ITransactionCallback action)
any idea what may be the reason?

The TransactionTemplate class in Spring.Net doesn't have virtual methods so RhinoMocks is unable to override the Execute method when you create the mock.
What this means is that you're not actually stubbing out the Execute method but calling through to the real method. That Execute method calls out to an IPlatformTransactionManager object which you haven't yet supplied and thus the null exception occurs.
Given that the Execute method is part of the ITransactionOperations interface, you may be able to get away with creating a mock ITransactionOperations object and using that in the rest of your test.
Alternatively you could try providing a mock IPlatformTransactionManager to the TransactionTemplate class, and also an ITransactionCallback.DoInTransaction() implemetation for using tDelegate.Stub().Do() syntax.
Something like this:
var transactionManager = MockRepository.GenerateMock<IPlatformTransactionManager>();
var mockDelegate = MockRepository.GenerateMock<ITransactionCallback>();
mockDelegate.Stub(t => t.DoInTransaction(null)).IgnoreArguments().Do(...);
var template = new TransactionTemplate(transactionManager);
template.Execute(mockDelegate);

Related

Using Moq in Castle.Windsor factory method throws

I have encountered a problem while using Moq (v4.8.1) in a factory method for Castle.Windsor (v4.1.0). I would like to know if anyone else has encountered this, and what they did to solve it.
I have a simple interface defined as:
interface IFoo
{
Task DoFooAsync(Bar bar);
}
In my main project I register the following in my WindsorContainer:
container
.Register(Component.For<IFoo, Foo>()
.LifestyleTransient());
This resolves nicely at runtime.
In my test project I do the following:
container.Register(Component.For<IFoo>().UsingFactorymethod(() => {
var mock = new Mock<IFoo>();
mock
.Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
.Returns(() => Task.FromResult(true));
return mock.Object;
})
.IsDefault());
This fails during test with the message from Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.ApplyCommissionConcerns(Object instance):
"Can not apply commission concerns to component Late Bound MyAssembly.IFoo because it appears to be a target-less proxy. Currently those are not supported."
Note: The 'IsDefault()' is only there to make Castle.Windsor override the registration from the main project, and it is not related to this problem (I tried running without it and the problem persists).
If I instead do the following:
// exact same code as above, just placed outside the factory method
var mock = new Mock<IFoo>();
mock
.Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
.Returns(() => Task.FromResult(true));
// different registration
container
.Register(Component.For<IFoo>()
.Instance(mock.Object).IsDefault());
Then everything works. But now my IFoo instance is reused each time IFoo is resolved - which is a different behavior than in my main project, and therfore not desired.
I have looked into the Castle.Windsor code to understand what is going on, but without real success.
Moq internally uses Castle's dynamic proxy and mocked class is in fact proxy generated by Castle and that's what for some internal reasons Castle's developers don't want to support. You can read about it more here:
https://github.com/castleproject/Windsor/issues/224
https://github.com/castleproject/castle-youtrack-export/blob/master/IOC/IOC-332.xml
So as Nkosi already commented, you should rather think about what you really need to achieve and reconsider your design.
"my IFoo instance is reused each time IFoo is resolved - which is a different behavior than in my main project, and therfore not desired."
What about creating a property with a lambda? Something like:
private IFoo TheMock => CreateMock();
private IFoo CreateMock()
{
var mock = new Mock<IFoo>();
mock
.Setup(x => x.DoFooAsync(It.IsAny<Bar>()))
.Returns(() => Task.FromResult(true));
return mock.Object;
}
And then register it
container
.Register(Component.For<IFoo>()
.Instance(TheMock).IsDefault());
Disclaimer: Haven't tested that, because I do not use Castle.Windsor.
This works for me. UsingFactoryMethod() was failing. It uses Nsubstitute for fake injection.
var blobservice = Substitute.For<IBlobFileService>();
RegisterFakeServiceInstance(blobservice);
private void RegisterFakeServiceInstance<TService>(TService fakeService) where TService : class
{
IocManager.IocContainer.Register(
Component.For<TService>()
.Instance(fakeService)
.LifestyleSingleton()
);
}

Mocking Library Method

I recently started tdd, but my mocking knowledge is incomplete. I know the basics but, Tests for some methods which were written without thinking tdd, really confuse me.
Here is what I am trying to test
public int GetThirdPartyUserId(int serviceTypeId, string accessToken)
{
ThirdPartyRequestDetail requestDetail = GetThirdPartyRequestDetails(serviceType, accessToken);
IHttwrapConfiguration configuration = new HttwrapConfiguration(requestDetail.BaseUrl);
IHttwrapClient httwrap = new HttwrapClient(configuration);
Task<IHttwrapResponse<OpenAuthUserResponse>> response = httwrap.GetAsync<OpenAuthUserResponse>(requestDetail.PathAndQuery);
try
{
if (response.Result.Data != null && response.Status != TaskStatus.Faulted)
{
//Do something
}
else
{
//WANT TO TEST HERE
}
}
}
Here is my test method
private Mock<IHttwrapClient> _httpwrap;
public void httprwapTest()
{
string accessToken = "invalid";
int thirdPartySiteId = (int)ThirdPartyServiceType.GooglePlus;
string requestPath = _fixture.Create<string>();
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
OpenAuthUserResponse response = _oauthAuthenticator.GetThirdPartyUser(thirdPartySiteId, accessToken);
Assert.AreEqual(response.Error, OauthAuthenticatorErrorType.RequestFaulted);
}
What I tried to do is below but it didn't get triggered.
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
How I can test my classes behaviour when httpwrap gives me a badrequest response code?
In it's current form, you can't use a conventional mocking framework to help with your test. In order for the Mocking to work, you have to Setup the same mock that you're using in your production code. Currently there's no connection between the mock you're creating in your test and the IHttpwrapClient that your method under test depends on.
The first step you would need to do take is to move the creation of the HttpwrapClient outside of the method that you want to test. You then need to make it available to the code, via it's interface, in a way that you can later supply it from your test.
There are three common ways of supplying the interface.
Inject it into the constructor for your class
Inject it through a property on your class
Pass it as an argument to the function
Generally constructor injection is preferred over property injection, but it's largely up to you which approach is going to work best (they each have positives and negatives) and what makes most sense for the data that you're injecting.
You would then create the Mock of your interface and inject it into your code as appropriate.
As far as your production code goes, you're still going to need to create an instance of your concrete class. You can either do this directly when calling your class, or via something like a factory, or by using an IoC container, like Castle Winsor or Ninject (there are several others).

Simple Injector, can't override existing registration

I am currently using Simple Injector for the first time. In my .NET project I am running test and mocking data returned from a web service and registering the object to the container like so
_container.Register<IWebServiceOrder>(() => mock.Object, Lifestyle.Transient);
This works fine. But in my tests I want to test the behavior of the system on a second call to the web service that will contain updated data, so the mock object will need to be updated.
By default Simple Injector does not allow Overriding existing registrations but the official website states it is possible to change this behavior like below.
https://simpleinjector.readthedocs.org/en/latest/howto.html#override-existing-registrations
container.Options.AllowOverridingRegistrations = true;
Unfortunately i still get an error when i try to register the object a second time even with the above code.
The container can't be changed after the first call to GetInstance, GetAllInstances and Verify
Any ideas on why this is happening?
Replacing an existing registration after you already worked with the container hardly ever has the behavior you would expect (and this holds for all DI libraries) and that's the reason why the Simple Injector container is locked. This is described in more details here (as #qujck already pointed out).
First of all, if you are writing unit tests, you shouldn't use a container at all. Your unit tests should create the class under test themselves, or you extract this logic to a convenient factory method, such as:
private static MailNotifier CreateMailNotifier(
IDeposit deposit = null, ISendMail mailSender = null, ILog logger = null)
{
return new MailNotifier(
deposit ?? Substitute.For<IDeposit>(),
mailSender ?? Substitute.For<ISendMail>(),
logger ?? Substitute.For<ILog>());
}
This factory method is a variation to the Test Data Builder pattern.
By making use of optional parameters, it allows the unit test to specify only the fake implementation it requires during testing:
public void Notify_WithValidUser_LogsAMessage()
{
// Arrange
var user = new User();
var logger = new FakeLogger();
MailNotifier sut = CreateMailNotifier(logger: logger);
// Act
sut.Notify(user);
// Assert
Assert.AreEqual(expected: 1, actual: logger.LoggedMessages.Count);
}
If you use a container, because creating the class under test by hand is too cumbersome, it indicates a problem in your class under test (most likely a Single Responsibility Principle violation). Prevent using tools to work around problems in your design; your code is speaking to you.
For integration tests however, it is much more usual to use the container, but in that case you should simply create a new container for each integration test. This way you can add or replace the IWebServiceOrder without any problem.

Mocking a dependency with AutoFixture

I've recently started using AutoFixture+AutoMoq and I'm trying to create an instance of Func<IDbConnection> (i.e., a connection factory).
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
This seems to work rather well:
My system under test can call the delegate and it will get a mock of IDbConnection
On which I can then call CreateCommand, which will get me a mock of IDbCommand
On which I can then call ExecuteReader, which will get me a mock of IDataReader
I now want to perform additional setups on the mock of IDataReader, such as make it return true when Read() is called.
From what I've read, I should be using Freeze for this:
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
This doesn't seem to meet my expectations though. When I call IDbCommand.ExecuteReader, I'll get a different reader than the one I just froze/setup.
Here's an example:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//true - Create<IDataReader> retrieves the data reader I just mocked
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDataReader>());
//false - IDbCommand returns a different instance of IDataReader
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
What am I doing wrong? How do I get other fixtures, such as IDbCommand, to use the mocked instance of IDataReader?
As of 3.20.0, you can use AutoConfiguredMoqCustomization. This will automatically configure all mocks so that their members' return values are generated by AutoFixture.
E.g., IDbConnetion.CreateCommand will be automatically configured to return an IDbCommand from the fixture, and IDbCommand.ExecuteReader will be automatically configured to return an IDataReader from the fixture.
All of these tests should pass now:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//all pass
Assert.Same(dataReaderMock.Object, fixture.Create<IDataReader>());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbConnection>().CreateCommand().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<Func<IDbConnection>>()().CreateCommand().ExecuteReader());
You have to Freeze the Mock<IDbCommand> as well – and setup the mock object (as a Stub) to return the existing dataReaderMock.Object instance.
If you add the following to the Arrange phase of you test, the test will pass:
var dbCommandStub =
fixture
.Freeze<Mock<IDbCommand>>()
.Setup(x => x.ExecuteReader())
.Returns(dataReaderMock.Object);
While the solution from Nikos works I would not I do not recommend mocking ado.net.
In my opinion your tests will probably be hard to understand, maintain and will not give you the confidence your tests should give you.
I would consider testing your data layer by going all the way to the database even though it is slower.
I would recommend reading this article regarding best practices for mocking:
http://codebetter.com/jeremymiller/2006/01/10/best-and-worst-practices-for-mock-objects/
Don't mock others:
http://aspiringcraftsman.com/2012/04/01/tdd-best-practices-dont-mock-others/
I don't know your exact situation but anyways I wanted to share this.

Rhino Mocks Stub Method not working

Why won't this test method work? I keep getting requires a return value or an exception to throw.
public AuthenticateResponse Authenticate(string username, string password)
{
string response = GetResponse(GetUrl(username, password).ToString());
return ParseResponse(response);
}
[TestMethod()]
[ExpectedException(typeof(XmlException))]
public void Authenticate_BadXml_ReturnException()
{
MockRepository mockRepository = new MockRepository();
SSO sso = mockRepository.Stub<SSO>();
sso.Stub(t => t.GetResponse("")).Return("<test>d");
AuthenticateResponse response = sso.Authenticate("test", "test");
}
Your repository is still in "record" mode. You're mixing record/replay semantics (the "old" way of doing things) with the newer AAA (arrange/act/assert) style.
Instead of creating your own repository, simply use:
var sso = MockRepository.GeneateStub<SSO>();
Everything should work fine now.
Your last line is calling the Authenticate method on your stub object, you haven't set up a return or value or exception to throw when calling it, so Rhino Mocks doesn't know what the stub should do and it causes an error. You probably don't want to call a method on your stub - that seems kind of pointless to me, is there another object (that you're actually testing in this test) that you should be calling a method on?
Is that your whole test? If so, your test makes no sense. The only object in your test is the one you're stubbing--where is the subject of the test?
If you're trying to test the SSO class, you absolutely never want to mock/stub it. If SSO has one or more dependencies, use the mocking framework to set up canned interactions between those dependencies and your SUT. That is the exact purpose of a mocking framework.

Categories

Resources