I have the below class, and I am trying to test the method AddRecordToQueue.
I am using Moq to mock the result of the the AddToQueue method within the AddRecordToQueue method.
The AddToQueue method returns a boolean, so i am trying to mock the result with a true value
public class Test
{
private readonly IRabbitMqConnection rabbitMqConnection;
public Test(IRabbitMqConnection rabbitMqConnection)
{
this.rabbitMqConnection = rabbitMqConnection;
}
public bool AddRecordToQueue(string messageExchange, object data)
{
var jsonified = JsonConvert.SerializeObject(data);
var customerBuffer = Encoding.UTF8.GetBytes(jsonified);
var result = this.rabbitMqConnection.AddToQueue(customerBuffer, messageExchange);
return result;
}
}
My test class looks like the below.
[TestClass]
public class TestCon
{
[TestMethod]
public void MockTest()
{
Moq.Mock<IRabbitMqConnection> rabbitConection = new Moq.Mock<IRabbitMqConnection>();
var draftContactsManager = new Test(rabbitConection.Object);
rabbitConection.Setup(e => e.AddToQueue(null, string.Empty)).Returns((bool res) => true);
var result = draftContactsManager.AddRecordToQueue("someExchange", null);
Assert.IsTrue(result);
}
}
I cant seem to set the moq result as true. Can anyone advise what I am missing
thanks
I think that you need to change the Returns to just return true instead of the lambda. Like this:
rabbitConection.Setup(e => e.AddToQueue(null, string.Empty)).Returns(true)
EDIT:
If this still doesn't work then it is probably due to the parameters not matching. You are passing in "someExchange" but the mock is set up for string.Empty. If you aren't sure what values will be used you could use the It.IsAny method to get around this.
rabbitConection.Setup(e => e.AddToQueue(It.IsAny<byte[]>(), It.IsAny<string>())).Returns(true)
You need to setup the method with the actual arguments it's invoked.
If JsonConvert.SerializeObject(data) returns null, then this is the setup:
rabbitConection.Setup(e => e.AddToQueue(null, "someExchange")).Returns(true)
Additionally, you can setup the method to return true/false regardless of values of the arguments:
rabbitConection.Setup(e => e.AddToQueue(It.IsAny<byte[]>(), It.IsAny<string>())).Returns(true)
With the above setup, the method will return true no matter what what you've passed to the method. The previous example will return true only when the method is called with the setuped arguments.
As the others said, the Setup is incorrect.
You need to call Setup before using the associated Object
It should be something similar to:
...
rabbitConection
.Setup(e => e.AddToQueue(It.IsAny<byte[]>(), It.IsAny<string>()))
.Returns(true);
var draftContactsManager = new Test(rabbitConection.Object);
...
Related
I have the following method under test:
public HomeController(IUserIpAddressHelper userIpAddressHelper)
{
_userIpAddressHelper = userIpAddressHelper;
}
[HttpGet]
public ActionResult Index()
{
var userIpAddress = _userIpAddressHelper.GetUserIpAddress(System.Web.HttpContext.Current);
if (_userIpAddressHelper.IsIpAddressOddOrEven(userIpAddress))
{
return RedirectToAction(HomePage);
}
return RedirectToAction(HomePageAlternative);
}
and I am testing as follows:
public void Test()
{
var userIpAddressHelper = Substitute.For<IUserIpAddressHelper>();
userIpAddressHelper.GetUserIpAddress(Arg.Any<HttpContext>()).Returns("0.0.0.2");
var controller = new HomeController(userIpAddressHelper);
var result = controller.Index();
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}
However the test is failing due to the value of userIpAddress being "" an empty string, instead of 0.0.0.2 as I've set it. Can anyone please point out where I've gone wrong here?
Is userIpAddress definitely ""? It looks like the Returns in your original test is specified well, but if IUserIpAddressHelper is an interface then the substitute for it will not have a result stubbed for IsIpAddressOddOrEven, so it will always return false even if GetUserIpAddress is stubbed to return "0.0.0.2".
To get the test to mirror how the production code passes through the data, you can stub out both members:
var userIpAddressHelper = Substitute.For<IUserIpAddressHelper>();
userIpAddressHelper.GetUserIpAddress(Arg.Any<HttpContext>()).Returns("0.0.0.2");
userIpAddressHelper.IsIpAddressOddOrEven("0.0.0.2").Returns(true);
This will test that the production code correctly passes through the result of GetUserIpAddress to IsIpAddressOddOrEven.
Note: we could also stub these to work with "ip-address-result" and it would still work. We don't need a valid odd/even result returned, as we are not using a real implementation of IUserIpAddressHelper, just a substitute for testing. If you find it necessary to substitute for IUserIpAddressHelper in lots of tests and you want it to act like a real implementation (i.e. it will actually return whether an address is odd or even), it might be easier to write a TestUserIpAddressHelper.
Another way to avoid having the dependency between the results of GetUserIpAddress and IsIpAddressOddOrEven is to change the interface to have a bool IsIpAddressOddOrEven(HttpContext context) method that combines both operations. That way you would only need to stub one for the test.
If you have problems with System.Web.HttpContext.Current, you can try to mock IsIpAddressOddOrEven method instead. They will both do the same job for your test.
Like this:
public void Test()
{
var userIpAddressHelper = Substitute.For<IUserIpAddressHelper>();
userIpAddressHelper.IsIpAddressOddOrEven(Arg.Any<string>()).Returns(true);
var controller = new HomeController(userIpAddressHelper);
var result = controller.Index();
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}
I need to mock a while loop to run just once however my setup makes it run infinite times as I think it returns true always.
My Set up:
var loginName = "12345";
cacheRepository.Setup(m => m.AddString(string.Format("{0}_{1}", Resources.ResetCodeCacheKey, randomCode), loginName)).Returns(true);
While loop in method:
while (_cacheRepository.AddString(string.Format("{0}_{1}", Resources.ResetCodeCacheKey, code), userLoginName))
{
//.........
}
Add String implementation:
public virtual bool AddString(string key, string value)
{
if (!ExistsKey(key))
{
Cache.AddString(key, value);
return true;
}
return false;
}
How can I set up my method to return true just once? A code snippet will be helpful.Thanks for looking into this.
Use SetupSequence to setup the mocked member to return the desired results.
For example say you have the following interface
public interface IInterface {
bool AddString(string key, string value);
}
The setup would look like
var cacheRepository = new Mock<IInterface>();
cacheRepository
.SetupSequence(m => m.AddString(It.IsAny<string>(), It.IsAny<string>()))
.Returns(true)
.Returns(false);
When the mocked member is called the first time is will return true and then false the second time.
Reference Moq Quickstart to get a better understanding of how to use the mocking framework.
Setting up a member to return different values / throw exceptions on sequential calls:
var mock = new Mock<IFoo>();
mock.SetupSequence(f => f.GetCount())
.Returns(3) // will be returned on 1st invocation
.Returns(2) // will be returned on 2nd invocation
.Returns(1) // will be returned on 3rd invocation
.Returns(0) // will be returned on 4th invocation
.Throws(new InvalidOperationException()); // will be thrown on 5th invocation
I am having a test method that asserts if the CreateClient method of the client account repository has been called. Please See the test bellow.
[TestMethod]
public void CreateNewBasicClientAccount_NewBasicClient_CreatesNewClientBasicClient()
{
// Arrange
var clientAccountToCreate = new ClientAccount
{
Name = "Name",
};
var clientAccountToCreateDto = AutoMapper.Mapper.Map<ClientAccount, ClientAccountDto>(clientAccountToCreate);
var clientAccountRepository = A.Fake<IClientAccountRepository>();
var clientAccountManager = new ClientAccountManager(clientAccountRepository);
// Act
clientAccountManager.CreateClient(clientAccountToCreate);
// Assert
A.CallTo(
() => clientAccountRepository.CreateClient(A<ClientAccountDto>.That.IsNotNull<ClientAccountDto>()))
.MustHaveHappened();
A.CallTo(
() => clientAccountRepository.CreateClient(A<ClientAccountDto>.Ignored))
.MustHaveHappened();
A.CallTo(
() => clientAccountRepository.CreateClient(clientAccountToCreateDto))
.MustHaveHappened();
}
The Act portion of my ClientAccountManager class in the test is calling the CreateClient method of the repository
public void CreateClient(ClientAccount client)
{
var clientDto = AutoMapper.Mapper.Map<ClientAccount, ClientAccountDto>(client);
_clientAccountRepository.CreateClient(clientDto);
}
The first two asserts in the test pass, but the more specific 3rd assert fails with result message
InterfaceNameSpace.IClientAccountRepository.CreateClient(clientDto: DtoNameSpace.ClientAccountDto)
Expected to find it at least once but found it #0 times among the calls:
Both the ClientAccount and ClientAccountDto classes have the exact same properties. Input in getting the failed assert to pass would be appreciated as the code is wired up for it to pass but it fails.
This is because the actual ClientAccountDto that is passed to the method is not the same instance as the one you create in your test, so they're not considered equal.
There are several options to solve this:
override the Equals method in ClientAccountDto (not ideal, since you normally wouldn't need this for a DTO)
inject an IMapper into ClientAccountManager, instead of using the static Mapper class, and configure the IMapper to return a specific instance of ClientAccountDto
test specific properties of the ClientAccountDto, like this:
A.CallTo(
() => clientAccountRepository.CreateClient(A<ClientAccountDto>.That.Matches(x => x.Name == "Name")))
.MustHaveHappened();
Unrelated note: you don't need to specify the type again in A<ClientAccountDto>.That.IsNotNull<ClientAccountDto>(), you can just write A<ClientAccountDto>.That.IsNotNull().
My generic class takes a Func<T> parameter in constructor, and I want to test one of its methods which basically invoke the constructor parameter.
I use Moq and in my test code is something like this:
[Fact]
public void Construct_EnsureInvokeFunction()
{
_objectToTest=new TypeToTest<T>(It.IsAny<Func<T>>());
_objectToTest.Construct();
//here I want to ensure that the passed parameter is invoked
//however since I can't mock Func<T>, I dont know how to verify
//whether Invoke method of Func<T> is triggered
}
One workaround that I can think is to wrap my Func<T> inside a new interface and create a method to wrap it's Invoke method, and then use Moq to mock the interface. However it doesn't seem effective.
Am I missing something? Any idea will be appreciated.
Thanks,
Anton
You can create a simple fake Func<T> closure with side-effects and verify those side-effects. A good one is incrementing a local variable because it also lets you assert that it was not called more than it should. Something like this:
int counter = 0;
Func<T> f = () => { counter++; return fakeT; }
var objectToTest = new TypeToTest<T>(f);
objectToTest.Construct();
Assert.Equal(1, counter);
You can wrap the Func<T> in an anonymous method that sets a local variable:
bool wasInvoked = false;
Func<T> testFunc = () => { var ret = funcToTest(); wasInvoked = true; return ret; }
// Test something with testFunc instead of funcToTest
...
Assert.IsTrue(wasInvoked);
Using the new Rhino Mocks 3.5 Arrange/Act/Assert (AAA) Testing style, I'm having problems writing a test.
I have a method that calls a method on a repository class. ActivateFoo, where my Foo object has an IsActive property. The result of the ActivateFoo object should change the property.
Here is sample code:
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).Return(true);
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
I'm guessing that the key piece of code would be inbetween "ActivateFoo(foo))." and "Return(true);".
One point to clarify how the method chaining stuff works behind the scenes, If there is code written on the line I expect, does it matter if it is after Return() or before? (unless of course the solution is using the MethodOptions overload of Expect, or something else).
Thanks in advance for any help.
Thanks to AB Kolan this is the resulting code I used and works.
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new Func<Foo, bool>(
delegate(Foo f) { f.IsActive = true; return true; }
));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
I tend to not like to have to have extra methods of functions for single use of a test, preferring an inline delegate if possible.
To address the issue of is this something I should be doing or not as far as the design. As the names are there, this isn't the exact code and inside of the target.Activate() method. The code in Activate() does some checking and if needed, will do the repository ActivateFoo(), and then check the result of that operation and do other things.
So, it might be possible that at a later time I will have to refactor this out and separate the steps, but for now, I've got it to work.
Thanks
You might want to try something out like this using the Do handler. I honestly feel ActivateFoo should be void return type. But here's the code for ActivateFoo with bool return type.
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
private delegate bool ActivateFooDelegate(Foo f);
public bool ActivateFooDelegateInstance(Foo f)
{
f.IsActive = true;
return f.IsActive;
}
I was not really using this version of RhinoMocks yet, but in the old versions you would have to use a .Do(appropriate delegate) to set the flag and return the value (instead of .Return).
Please let me know if it works, if not I can play around with it.
From the looks of it, ActivateFoo should be a void method. And since you are mocking it out, you shouldn't be verifying that it changes anything on your object.
You would verify that the IsActive property is changed when you were testing your repository method ActivateFoo, not when you are testing the Activate method on the presenter.