Im trying to mock a method, it compiles without errors, but smth strange happens when i run a test. Actually method doesnt mock or maybe I dont understand smth...(
Here's a code:
public class Robot
{ ....
public virtual bool range(IObs ob, double range)
{
double dist = ob.distanceSq(this);
if (dist < range)
return true;
else
return false;
}
}
...
public interface IObs
{
double distanceSq(Robot r);
}
...
Unit Test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
MockRepository mocks = new MockRepository();
IObs obstacleMock = mocks.CreateMock<IObs>();
Robot r = new Robot();
Expect.Call(obstacleMock.distanceSq(r)).IgnoreArguments()
.Constraints(Is.Anything())
.Return(5.5);
Assert.IsTrue(r.range(obstacleMock, 0.5));
}
}
I mock distanceSq().
When I debug my test, i see that ob.distanceSq(this) is 0.0. (not 1.5).
What's wrong?
Your code does not actually use mock you created - as you can change Obstacle to IObjs as argument of range and than pass mock instead of new instance of Obstacle:
public virtual bool range(IObjs ob, double range)....
class Obstacle : IObjs ...
Assert.IsTrue(r.range(obstacleMock, 0.5));
I would recommend that you upgrade your RinoMocks version to 3.6 and use the new syntax.
Additionally if you are using a mock for IObs, you may as well verify that the distanceSq method is called.
I have left the verification of the parameters in the distanceSq method out of this code, but you could ensure that the correct Robot instance is passed in.
The unit test will still fail however, as 5.5 is greater than 0.5
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
namespace Rhino
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var r = new Robot();
var obstacleMock = MockRepository.GenerateMock<IObs>();
obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Anything)).Return(5.5);
//use this line to ensure correct Robot is used as parameter
//obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Equal(r))).Return(5.5);
var result = r.range(obstacleMock, 0.5);
obstacleMock.VerifyAllExpectations();
Assert.IsTrue(result);
}
}
public class Robot
{
public virtual bool range(IObs ob, double range)
{
return ob.ditanceSq(this) < range;
}
}
public interface IObs
{
double ditanceSq(Robot r);
}
}
Related
I wrote the following test case to illustrate my problem using Rhino Mocks:
[TestClass]
public class Tester
{
public class TestList<T> : List<T>
{
public override bool Equals(object obj)
{
// obj is an empty list here??
return base.Equals(obj);
}
}
public interface IStubbedInterface
{
void DoSomethingWithList(TestList<int> list);
}
public class ClassToTest
{
public IStubbedInterface TheStub { get; set; }
public void Run()
{
var list = new TestList<int> { 1, 2 };
TheStub.DoSomethingWithList(list);
list.Clear();
}
}
public bool Match(TestList<int> arg)
{
// Here arg is an empty list??
return arg == new TestList<int> { 1, 2 };
}
[TestMethod]
public void Test()
{
var classToTest = new ClassToTest();
classToTest.TheStub = MockRepository.GenerateMock<IStubbedInterface>();
classToTest.Run();
classToTest.TheStub.AssertWasCalled(
x => x.DoSomethingWithList(new TestList<int>() { 1, 2 }));
//x => x.DoSomethingWithList(Arg<TestList<int>>.Matches(arg => Match(arg))));
}
}
The test case will fail on the AssertWasCalled() line, no matter if I compare the list directly or using the Arg<>.Matches(..) syntax. I also tried with MockRepository.GenerateStub<>(..) instead of GenerateMock<>(..), which also fails. It fails because of the list.Clear(); line after calling DoSomethingWithList(), which results in the list also being empty at the time of AssertWasCalled(). Is this a bug with RhinoMocks? I would have assumed that RhinoMocks would record a snapshot of the argument somehow when the asserted function was called, but it looks like RhinoMocks keeps using the same object?
In the real case where I encountered this problem the argument of the function I was testing was wrapped in a using() statement, which lead to the same effect of AssertWasCalled not being able to test the arguments passed.
Looks like using the Expect()/VerifyAllExpectations() pattern works better for this test scenario. Changing the test case to the below code will pass.
This is rather unfortunate as I much prefer using AssertWasCalled(), however as it stands it is rather unreliable.
[TestMethod]
public void Test()
{
var classToTest = new ClassToTest();
classToTest.TheStub = MockRepository.GenerateMock<IStubbedInterface>();
classToTest.TheStub.Expect(
x => x.DoSomethingWithList(new TestList<int>() { 1, 2 }));
classToTest.Run();
classToTest.TheStub.VerifyAllExpectations();
}
I have a simple function that takes Client and Supplier data and then calculates tax based on where they live and other information:
static int CountTax(Supplier tiek, Client kl, bool same_country)
{
if ( !tiek.is_PVM_payer)
return 0;
else
{
if (!kl.EU)
return 0;
else
{
if (same_country)
return kl.x;
else
{
if (kl.is_PVM_payer)
return 0;
else
return kl.x;
}
}
}
}
Now I am required to write tests for this function. It is the first time I am encountering tests. I am using XUnit testing. And my test class looks like this:
using System;
using Xunit;
namespace CountTax_tests
{
public class UnitTest1
{
[Theory]
[InlineData(typeof(Client))]
public void Tax_is_0()
{
// arrange
int expectedVal = 0;
int actualVal;
/// act
actualVal = MyProgram.MyprogramCode.CountTax(supplier, client, same_country);
// assert
Assert.Equal(expectedVal, actualVal);
}
[Fact]
public void PVM_is_x()
{
int expectedVal = x;
int actualVal;
actualVal = MyProgram.MyprogramCode.CountTax(supplier, client, same_country);
Assert.Equal(expectedVal, actualVal);
}
}
}
But how do I pass my Client and Supplier parameters to that test? Please help me and lead on a path because I am completely new and nothing is clear to me even after many tutorials...
Maybe I have to use [Theory]? Or maybe [Fact]? Or maybe it is impossible to pass classes as parameters?
Also, [InlineData(typeof(Client))] is being underlined in red and is not working.
I am trying to test a class which instatiates another class within it. It is the instatinated class call I want to mock.
Is this possible or is they a way around it/ simpler way I am missing?
Below I have written up a simpler example which still has the same problemts as my main code.
public interface my_interface
{
int returns_25();
}
public class class_i_want_to_mock : my_interface
{
public int returns_25()
{
// TEST SHOULD FAIL SO NEED MOCK TO PASS THE CASE
return 7645745;
}
}
In another namespace (it has access):
public class class_to_test
{
public static int returns_25()
{
class_i_want_to_mock _tempClass= new class_i_want_to_mock ();
// Will return 7645745 unless moq changes return value
int _temp_int = _tempClass.returns_25()
return _temp_int;
}
}
My test (which fails):
[Test]
public void test_returns_25()
{
// Mock
Mock<my_interface> myMock = new Mock<my_interface>();
myMock.Setup(m => m.returns_25()).Returns(25);
// Act
int return_number = class_to_test.returns_25();
// Assert
Assert.AreEqual(25, return_number);
}
Here is working code thanks to the injection idea from JSteward above.
Code is in same order
public interface my_interface
{
int returns_25();
}
public class class_i_want_to_mock : my_interface
{
public int returns_25()
{
// TEST SHOULD FAIL SO NEED MOCK TO PASS THE CASE
return 7645745;
}
}
Next class, notice the injection of the interface
public class class_to_test
{
public static int returns_25(my_interface _temp_interface)
{
// Will return 7645745 unless moq changes return value
int _temp_int = _temp_interface.returns_25()
return _temp_int;
}
}
And the test. Note the object of the Mock class has to be used (myMock.Object)
[Test]
public void test_returns_25()
{
// Mock
Mock<my_interface> myMock = new Mock<my_interface>();
myMock.Setup(m => m.returns_25()).Returns(25);
// Act
int return_number = class_to_test.returns_25(myMock.Object);
// Assert
Assert.AreEqual(25, return_number);
}
I'm working on a unit test for a service method, that has dependencies. Simplified:
public class ConditionChecker
{
private SqlConnection _connection;
public bool CanDoSomething()
{
return _connection.State == ConnectionState.Open;
}
}
public class A
{
public ConditionChecker Checker { get; set; }
public bool CanInvokeA()
{
return Checker.CanDoSomething();
}
}
[TestClass]
public class ATests
{
[TestMethod]
public void TestCanInvokeA()
{
// arrange
A a = new A();
ConditionChecker checker = MockRepository.GenerateStub<ConditionChecker>();
checker.Stub(x => x.CanDoSomething()).Return(true);
a.Checker = checker;
// act
bool actual = a.CanInvokeA();
// assert
Assert.AreEqual(true, actual);
}
}
What I want is to completely bypass the implementation of ConditionChecker.CanDoSomething, which is why I stub the call, still I run into a null reference Exception during my test, since the _connection member is not set. What am I doing wrong here?
You just mark your method as virtual, it will work:
public virtual bool CanDoSomething()
{
}
Since behind the scene Rhino Mock will create a dynamic proxy for ConditionChecker, so you need to mark virtual to allow Rhino Mock to override it.
public interface IServiceInvoker
{
R InvokeService<T, R>(Func<T, R> invokeHandler) where T : class;
}
public class MediaController : Controller
{
private IServiceInvoker _serviceInvoker;
public MediaController(IServiceInvoker serviceInvoker)
{
_serviceInvoker = serviceInvoker;
}
public JsonResult GetAllMedia()
{
var media = _serviceInvoker.InvokeService<IMediaService, List<MediaBase>>(proxy => proxy.GetAllMediaInJson());
JsonResult jsonResult = new JsonResult();
jsonResult.Data = media;
jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsonResult;
}
[TestClass]
public class MediaControllerTests
{
[TestMethod]
public void GetAllMedia()
{
JsonResult data;
var serviceInvoker = MockRepository.GenerateStub<IServiceInvoker>();
var media = CreateSeveralMedia();
serviceInvoker.Stub(c => c.InvokeService<IMediaService, List<MediaBase>>(p => p.GetAllMediaInJson())).Return(media);
data = new MediaController(serviceInvoker).GetAllMedia();
serviceInvoker.VerifyAllExpectations();
Assert.IsNotNull(data);
}
}
I am stubbing the service and returning a collection. When I run this test, media is null. Any idea, how can I set expectations on this mock ?
Just found a solution. It seems to be a little ugly, but it is the first iteration only probably more elegant version will appear soon. The idea is to create another stub and match Func<> against it:
I will provide code for my use case:
[Theory]
[InlineData(342, 31129, 3456)]
public void should_call_service_invoker_and_return_result(int number1, int number2, int expected)
{
var calculator = MockRepository.GenerateStub<ICalculator>();
calculator.Stub(_ => _.Add(number1, number2)).Return(expected);
var serviceInvoker = MockRepository.GenerateStub<ServiceInvoker<ICalculator>>();
serviceInvoker
.Stub(_ => _.Invoke(Arg<Func<ICalculator, int>>.Matches(d => d(calculator) == calculator.Add(number1, number2))))
.Return(expected);
var serviceConsumer = new ServiceConsumer(serviceInvoker);
var actual = serviceConsumer.GetAddResultFor(number1, number2);
Assert.Equal(expected, actual);
}
xUnit + extensions is used as testing framework. Please ignore Theory and InlineData stuff -- it is just another way to get rid of unnecessary test setup.
Here is the code of SUT:
public class ServiceConsumer
{
private readonly ServiceInvoker<ICalculator> serviceInvoker;
public ServiceConsumer(ServiceInvoker<ICalculator> serviceInvoker)
{
this.serviceInvoker = serviceInvoker;
}
public int GetAddResultFor(int number1, int number2)
{
return serviceInvoker.Invoke(_ => _.Add(number1, number2));
}
}
public class ServiceInvoker<T>
{
public virtual R Invoke<R>(Func<T, R> func)
{
throw new NotImplementedException();
}
}
public interface ICalculator
{
int Add(int number1, int number2);
}
Hope this will be helpful. Any suggestions of how to add more beauty are welcome :)
The lambda in your unit test compiles into a class-level method (a method inside your unit test). Inside your controller, a different lambda compiles into a class-level method (inside the controller). The stub set up in your unit test doesn't match the stub being executed in your controller, so Rhino Mocks returns a default (null). More here: http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1