I have an 'Example' class and I would like to create unit test for it. Take a look on my classes below:
public class Example
{
private readonly Calculator _calculator;
public Example(ICalculator calculator)
{
_calculator = calculator;
}
public void Calculate()
{
_calculator.Execute(operation => operation.Subtract());
}
}
public interface IOperation {
void Sum();
void Subtract();
}
public inferface ICalculator {
void Execute(Action<IOperation> action);
}
public class Calculator {
public void Execute(Action<IOperation> action){}
}
What I want is to create a Unit Test class to verify that my method from Example class Calculate calls the _calculator.Execute passing as parameter the operation.Subtract(). Is it possible?
I know how to mock my ICalculator and verify that Execute is being called once, but I have no idea how to validade if Execute method was called using operation.Subtract() as parameter instead of operation.Sum().
I am using NUnit to create my unit tests. Here you can see how my unit test class is at the moment:
[TestFixture]
public class ExampleTests
{
[Test]
public void Test1()
{
var calculator = new Mock<ICalculator>();
var subject = new Example(calculator.Object);
subject.Calculate();
calculator.Verify(x => x.Execute(It.IsAny<Action<IOperation>>()), Times.Once);
}
}
Hope someone can understand my english, sorry about that.
You cannot directly verify what lambda was passed but you can go around it by actually invoking said lambda with yet another mock:
var calculator = new Mock<ICalculator>();
var operation = new Mock<IOperation>();
// when calculator's Execute is called, invoke it's argument (Action<IOperation>)
// with mocked IOperation which will later be verified
calculator
.Setup(c => c.Execute(It.IsAny<Action<IOperation>>()))
.Callback<Action<IOperation>>(args => args(operation.Object));
var example = new Example(calculator.Object);
example.Calculate();
calculator.Verify(c => c.Execute(It.IsAny<Action<IOperation>>()));
operation.Verify(o => o.Subtract());
You're passing anonymous delegate operation => operation.Subtract() to _calculator.Execute - so you cannot construct it later when asserting for argument.
You can get around it by doing this:
public class Example
{
private readonly ICalculator _calculator;
public Example(ICalculator calculator)
{
_calculator = calculator;
}
public Action<IOperation> Subtract = op => op.Subtract();
public Action<IOperation> Add = op => op.Sum();
public void Calculate()
{
_calculator.Execute(Subtract);
}
}
And asserting like this (ommiting 2nd param defaults to Once):
calculator.Verify(x => x.Execute(subject.Subtract));
However this looks like convoluted design in order to be able to write a test.
Related
I am using AutoFixture to mock an external library that doesn't always implement interfaces, but has a default ctor without parameters.
Currently, I am using Moq/AutoMoq framework like that:
mocker.GetMock<HeavyDependency>()
.Setup(x => x.GetData())
.Returns("TEST DATA");
I want to have the same behaviour with AutoFixture.AutoMoq. My code:
namespace AutoFixtureNUnit.TestsCs
{
public class HeavyDependency1
{
public HeavyDependency1() => Debug.WriteLine("HeavyDependency1");
}
public class HeavyDependency2
{
public HeavyDependency2() => Debug.WriteLine("HeavyDependency2");
}
public class MyClassWithHeavyDependency
{
private readonly HeavyDependency1 dep1;
private readonly HeavyDependency2 dep2;
public MyClassWithHeavyDependency() => Debug.WriteLine("MyClassWithHeavyDependency default.");
public MyClassWithHeavyDependency(HeavyDependency1 h1, HeavyDependency2 h2)
{
Debug.WriteLine("MyClassWithHeavyDependency injected.");
dep1 = h1;
dep2 = h2;
}
}
[TestFixture]
public class TestClass
{
private Fixture _fixture;
private Mock<HeavyDependency1> _heavyMock;
MyClassWithHeavyDependency _sut;
[SetUp]
public void SetUp()
{
_fixture = new Fixture();
_fixture
.Customize(new ConstructorCustomization(typeof(MyClassWithHeavyDependency), new GreedyConstructorQuery()))
.Customize(new AutoMoqCustomization(){ConfigureMembers = false});
_heavyMock = new Mock<HeavyDependency1>();
_fixture.Inject(_heavyMock.Object);
_sut = _fixture.Create<MyClassWithHeavyDependency>();
}
[Test]
public void TestMethod()
{
Assert.Pass("Your first passing test");
}
}
}
MyClassWithHeavyDependency has a ctor that takes dependent objects and code above calls that ctor.
So far so good. I am injecting the Mock of the dependent object and verifying calls.
The problem:
For the mocks that are Injected, the constructor is called with the Mock like: {Mock<AutoFixtureNUnit.TestsCs.HeavyDependency1:00000001>.Object}.
However, for all other types it is called with the parameter of {AutoFixtureNUnit.TestsCs.HeavyDependency2}. Which is not what I want and is not used by the current tests. Not a Moq object, right?
It is mocking my own interfaces as well.
Question:
Can I somehow specify that AutoFixture.AutoMoq should mock all ctor parameters that are not manually mocked by me?
Because Freezing/injecting every single one is not different from manual mock setup and requires a lot of code changes every time I add ctor parameter.
Actually, I can see HeavyDependency1 ctor called as well. Seems strange.
I'm new to unit testing.
I have to test RefreshAmount in the following code:
private readonly int id;
private readonly IService service;
public MyClass(int id, IService service)
{
this.id= id;
this.service= service;
}
public double Number { get; private set; }
public void RefreshAmount()
{
Number= service.GetTotalSum(id);
}
What would be a correct unit test to write for RefreshAmount?
You need to mock IService. There are various frameworks that help automate this for you (like Moq) but here's a simple example:
public class MockService : IService
{
public double GetTotalSum(int id)
{
return 10;
}
}
Basically, a mock implements your interface but just returns hard-coded (or otherwise well-known) data. That makes it easy to know what your expected value should be! Now you can use that to do your test:
public void TestMethod()
{
MyClass testObj = new MyClass(1, new MockService());
testObj.RefreshAmount();
Assert.Equals(10, testObj.Number);
}
Start simple attempting the "Sunny Day" or "Happy Path" first...
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var service = new MyService();
int SomeProperInteger = GetNextInteger();
double SomeProperAmount = .50;
var actual = service.GetTotalSum(SomeProperInteger);
double expected = SomeProperInteger * SomeProperAmount;
Assert.IsTrue(expected = actual, "Test Failed, Expected amount was incorrect.");
}
private int GetNextInteger()
{
throw new System.NotImplementedException();
}
}
Start with testing a service object that will be used in production as shown above. You will have to look at the code to see what GetTotalSum is supposed to do or look at the specifications. Once the "Happy path" works then you will alter at most 1 parameter at a time using Boundaries. The Boundaries would in code above come from GetNextInteger or a list of proper values. You must write code to anticipate the expected value to compare.
After the service is validated to be working as designed, move on to the class that uses the service using the same techniques.
I'm trying to write a wrapper for a Selenium test that re-runs the test if it fails, I've got the mechanics working fine. But I need to figure out a way of passing either a function/method or (preferably) multiple methods inside of the function. Here's an example of what I want to achieve:
In the wrapper class:
public class TestRunner{
public void RunTest(function FuncToRun){
FuncToRun();
}
}
In the test:
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(Test());
}
This is purely for demonstration. I know that this doesn't work, but I hope it will convey my point to you.
Looks as though you need a delegate.
An applicable delegate for your scenario is the Action delegate which can be used to represent a single parameterless method.
public class TestRunner
{
public void RunTests(params Action[] tests)
{
foreach (var test in tests)
{
test.Invoke();
}
}
}
Note the use of the params keyword which will allow you ro supply any number of tests to the RunTests method. Here is an example using an implicit method group conversion:
public class Tests
{
public void TestOne() {
}
public void TestTwo() {
}
}
...
var runner = new TestRunner();
var tests = new Tests();
runner.RunTests(tests.TestOne, tests.TestTwo);
You could use Action parameters to do this
public class TestRunner{
public void RunTest(Action FuncToRun){
FuncToRun();
}
}
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(() => Test());
}
You want to do something like this. But need more context as in inputs and what return value you are expecting.
Func<string, int> myMethodName
This is an example of usage:
public bool RunThisMethod(Func<string, int> myMethod)
{
//... do stuff
int i = myMethod("My String");
//... do more stuff
return true;
}
use delegate . simply declare a delegate to the method you want to pass and call and assign the method to it.
http://msdn.microsoft.com/en-IN/library/ms173171.aspx
You may use delegates or even Action or Func objects.
public class TestRunner{
public void RunTest(Action funcAction){
funcAction();
}
}
public class Tests{
public void Test(){}
TestRunner.RunTest(Test);
}
I have been using MSpec to write my unit tests and really prefer the BDD style, I think it's a lot more readable. I'm now using Silverlight which MSpec doesn't support so I'm having to use MSTest but would still like to maintain a BDD style so am trying to work out a way to do this.
Just to explain what I'm trying to acheive, here's how I'd write an MSpec test
[Subject(typeof(Calculator))]
public class when_I_add_two_numbers : with_calculator
{
Establish context = () => this.Calculator = new Calculator();
Because I_add_2_and_4 = () => this.Calculator.Add(2).Add(4);
It should_display_6 = () => this.Calculator.Result.ShouldEqual(6);
}
public class with_calculator
{
protected static Calculator;
}
So with MSTest I would try to write the test like this (although you can see it won't work because I've put in 2 TestInitialize attributes, but you get what I'm trying to do..)
[TestClass]
public class when_I_add_two_numbers : with_calculator
{
[TestInitialize]
public void GivenIHaveACalculator()
{
this.Calculator = new Calculator();
}
[TestInitialize]
public void WhenIAdd2And4()
{
this.Calculator.Add(2).Add(4);
}
[TestMethod]
public void ThenItShouldDisplay6()
{
this.Calculator.Result.ShouldEqual(6);
}
}
public class with_calculator
{
protected Calculator Calculator {get;set;}
}
Can anyone come up with some more elegant suggestions to write tests in this way with MSTest?
What you think about this one:
[TestClass]
public class when_i_add_two_numbers : with_calculator
{
public override void When()
{
this.calc.Add(2, 4);
}
[TestMethod]
public void ThenItShouldDisplay6()
{
Assert.AreEqual(6, this.calc.Result);
}
[TestMethod]
public void ThenTheCalculatorShouldNotBeNull()
{
Assert.IsNotNull(this.calc);
}
}
public abstract class with_calculator : SpecificationContext
{
protected Calculator calc;
public override void Given()
{
this.calc = new Calculator();
}
}
public abstract class SpecificationContext
{
[TestInitialize]
public void Init()
{
this.Given();
this.When();
}
public virtual void Given(){}
public virtual void When(){}
}
public class Calculator
{
public int Result { get; private set; }
public void Add(int p, int p_2)
{
this.Result = p + p_2;
}
}
Mark Nijhof has an example of doing Given-When-Then style testing with NUnit in his Fohjin.DDD github repository.
Here's an excerpt from the example referenced above:
public class When_registering_an_domain_event : BaseTestFixture<PreProcessor>
{
/* ... */
protected override void When()
{
SubjectUnderTest.RegisterForPreProcessing<ClientMovedEvent>();
SubjectUnderTest.Process();
}
[Then]
public void Then_the_event_processors_for_client_moved_event_will_be_registered()
{
IEnumerable<EventProcessor> eventProcessors;
EventProcessorCache.TryGetEventProcessorsFor(typeof(ClientMovedEvent), out eventProcessors);
eventProcessors.Count().WillBe(1);
}
}
And you can see the Given in the base class implementation:
[Given]
public void Setup()
{
CaughtException = new NoExceptionWasThrownException();
Given();
try
{
When();
}
catch (Exception exception)
{
CaughtException = exception;
}
finally
{
Finally();
}
}
I've been giving this sort of question a lot of though recently. There are a lot of reasonable options out there, and you can create your own easily, as displayed in some of the answers in this post. I've been working on a BDD testing framework with the intent being to make it easily extended to any unit testing framework. I currently support MSTest and NUnit. Its called Given, and it's opensource. The basic idea is pretty simple, Given provides wrappers for common sets of functionality which can then be implemented for each test runner.
The following is an example of an NUnit Given test:
[Story(AsA = "car manufacturer",
IWant = "a factory that makes the right cars",
SoThat = "I can make money")]
public class when_building_a_toyota : Specification
{
static CarFactory _factory;
static Car _car;
given a_car_factory = () =>
{
_factory = new CarFactory();
};
when building_a_toyota = () => _car = _factory.Make(CarType.Toyota);
[then]
public void it_should_create_a_car()
{
_car.ShouldNotBeNull();
}
[then]
public void it_should_be_the_right_type_of_car()
{
_car.Type.ShouldEqual(CarType.Toyota);
}
}
I tried my best to stay true to the concepts from Dan North's Introducting BDD blog, and as such, everything is done using the given, when, then style of specification. The way it is implemented allows you to have multiple givens and even multiple when's, and they should be executed in order (still checking into this).
Additionally, there is a full suite of Should extensions included directly in Given. This enables things like the ShouldEqual() call seen above, but is full of nice methods for collection comparison and type comparison, etc. For those of you familiar with MSpec, i basically ripped them out and made some modifications to make them work outside of MSpec.
The payoff, though, I think, is in the reporting. The test runner is filled with the scenario you've created, so that at a glance you can get details about what each test is actually doing without diving into the code:
Additionally, an HTML report is created using t4 templating based on the results of the tests for each assembly. Classes with matching stories are all nested together, and each scenario name is printed for quick reference. For the above tests the report would look like this:
Failed tests would be colored red and can be clicked to view the exception details.
That's pretty much it. I'm using it in several projects I'm working on, so it is still being actively developed, but I'd describe the core as pretty stable. I'm looking at a way to share contexts by composition instead of inheritance, so that will likely be one of the next changes coming down the pike. Bring on the criticism. :)
You could use NUnit.Specifications and write tests like this:
using NUnit.Specifications;
using Should;
public class OrderSpecs
{
[Component]
public class when_a_customer_places_an_order : ContextSpecification
{
static OrderService _orderService;
static bool _results;
static Order _order;
Establish context = () =>
{
_orderService = new OrderService();
_order = new Order();
};
Because of = () => _results = _orderService.PlaceOrder(_order);
It should_successfully_place_the_order = () => _results.ShouldBeTrue();
}
}
MSTestEnhancer may help you, and you can get the package through NuGet.org.
Here is the sample code:
[TestClass]
public class TheTestedClassTest
{
[ContractTestCase]
public void TheTestedMethod()
{
"When Xxx happens, results in Yyy.".Test(() =>
{
// Write test case code here...
});
"When Zzz happens, results in Www.".Test(() =>
{
// Write test case code here...
});
}
}
And when you see your test result, you'll get this below:
I have written a post to present more information about it. See Introducing MSTestEnhancer to make unit test result easy to read - walterlv for more details.
Just starting out with Rhino Mocks and im having a very simple problem, how do I mock a class with a void which sets a property?
class SomeClass : ISomeClass
{
private bool _someArg;
public bool SomeProp { get; set; }
public SomeClass(bool someArg)
{
_someArg = someArg;
}
public void SomeMethod()
{
//do some file,wcf, db operation here with _someArg
SomeProp = true/false;
}
}
Obviously this is a very contrived example, Thanks.
In your example you won't need RhinoMocks because you're apparently testing the functionality of the class under test. Simple unit testing will do instead:
[Test]
public void SomeTest()
{
var sc = new SomeClass();
// Instantiate SomeClass as sc object
sc.SomeMethod();
// Call SomeMethod in the sc object.
Assert.That(sc.SomeProp, Is.True );
// Assert that the property is true...
// or change to Is.False if that's what you're after...
}
It's much more interesting to test mocks when you have a class that has dependencies on other classes. In your example you mention:
//do some file, wcf, db operation here with _someArg
I.e. you expect some other class to set SomeClass's property, which makes more sense to mocktest. Example:
public class MyClass {
ISomeClass _sc;
public MyClass(ISomeClass sc) {
_sc = sc;
}
public MyMethod() {
sc.SomeProp = true;
}
}
The required test would go something like this:
[Test]
public void MyMethod_ShouldSetSomeClassPropToTrue()
{
MockRepository mocks = new MockRepository();
ISomeClass someClass = mocks.StrictMock<ISomeClass>();
MyClass classUnderTest = new MyClass(someClass);
someClass.SomeProp = true;
LastCall.IgnoreArguments();
// Expect the property be set with true.
mocks.ReplayAll();
classUndertest.MyMethod();
// Run the method under test.
mocks.VerifyAll();
}
Depends on how much fidelity you'd like in your mock object. The easy way to do it is to not worry about it and write out some dumb expect statements.
[Test]
public void SomeTest()
{
MockRepository mocks = new MockRepository();
ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
using(mocks.Record())
{
using(mocks.Ordered())
{
Expect.Call(MockSomeClass.SomeProp).Return(false);
Expect.Call(delegate{MockSomeClass.SomeMethod();});
Expect.Call(MockSomeClass.SomeProp).Return(true);
}
}
}
If you want something that acts more like the real object without a canned set of ordered responses you'll have to set up delegates with the do method on the expect.
delegate bool propDelegate();
delegate void methodDelegate();
private bool m_MockPropValue = false;
[Test]
public void SomeTest()
{
MockRepository mocks = new MockRepository();
ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
using(mocks.Record())
{
SetupResult.For(MockSomeClass.SomeProp).Do(new propDelegate(delegate
{
return this.m_MockPropValue;
}));
Expect.Call(delegate{MockSomeClass.SomeMethod();}).Do(new methodDelegate(delegate
{
this.m_MockPropValue = true;
}));
}
}
When your preparing something with either SetupResult.For or Expect.Call you need to ensure that they are virtual, otherwise RhinoMocks will be unable to make its own implementation.
Otherwise it's just a matter of setting the results and doing expected calls as Scott Pedersen has shown
It's not totally clear from the question what the object you're trying to test is - if you simply want to check that SomeClass.SomeMethod() sets a property then you don't need mocking since you can just do a simple state-based test:
[TestMethod]
public void SomeMethodTest()
{
SomeClass s = new SomeClass();
s.SomeMethod();
Assert.AreEqual(expectedValue, s.SomeProp);
}
Alternatively, if SomeClass is a dependency for some other class, and you want to test the interaction between that class and SomeClass, then you set up the expectation on the method call during the 'Record' section of the test using RhinoMock, like this:
[TestMethod]
public void CheckInteractionWithSomeClass()
{
MockRepository mocks = new MockRepository();
ISomeClass someClass = mocks.StrictMock<ISomeClass>();
using (mocks.Record())
{
//record expection that someClass.SomeMethod will be called...
someClass.SomeMethod();
}
using (mocks.Playback())
{
//setup class under test - ISomeClass is injected through the constructor here...
ClassUnderTest o = new ClassUnderTest(someClass);
o.MethodOnClassUnderTestThatShouldCallSomeClass.SomeMethod();
//any other assertions...
}
}