How to refactor to avoid using a Shim? - c#

I'm pretty new to Unit Testing and am exploring the Microsoft Fakes framework - primarily because it's free and it allows me to mock SharePoint objects easily with the Emulators package. I've seen various mentions on SO and elsewhere that Shims are evil and I more or less understand why. What I don't get is how to avoid them in one specific case - in other words, "how should I refactor my code to avoid having to use shims?"
For the code in question, I have a JobProcessor object that has properties and methods, some of which are private as they should only be called from the public Execute method. I want to test that when Execute is called and there is a Job available that its Process method is called as I need to do some extra logging.
Here's the relevant code:
//in system under test - JobProcessor.cs
private IJob CurrentJob { get; set; }
public void Execute()
{
GetJobToProcess(); //stores Job in CurrentJob property if found
if (ShouldProcessJob){
CurrentJob.ProcessJob();
}
}
I need to do some extra things if ProcessJob is called from a test, so I set up a Stub in my Test Method to do those extra things:
StubIJob fakeJob = new StubIJob(){
ProcessJob = () =>{
//do my extra things here
}
};
I'm testing the ProcessJob method itself elsewhere so I don't care that it doesn't do anything but my extra stuff here. As I understand things, I now need to set up a Shim to have the private method GetJobsToProcess from JobProcessor (my system under test) return my fake job so that my stubbed method is called:
processor = new JobProcessor();
ShimJobProcessor.AllInstances.GetJobToProcess = (#this) =>{
var privateProcessor = new PrivateObject(processor);
privateProcessor.SetProperty("CurrentJob", fakeJob); //force my test Job to be processed so the Stub is used
};
In this case, how should I avoid using the Shim? Does it matter?
Thanks.

This is a case where rather than using a shim or stub, I'd just make the method return a boolean to notify whether or not the inner call has happened.
The problem with using fakes there is that you're assuming that some method of some object is called, which the test should not know. Tests should be dumb, and only see the outside of the code. Tests, like any other code, should not care how a value was reached, just that it is correct.
However, your code has another issue as well. You're getting some unknown object and using it within the same scope. You should remove the call to GetJobToProccess from Execute.
It's the principle of Dependency Injection: a method should not spin up and hide it's dependencies; if it depends on an object, that object should be possible to change freely or be passed in. The exact implementation of the job should not matter to the execute method, and that, along with the naming, implies that you should not be getting that object and executing it in the same call.

Related

Testing methods with overloading using shims and stubs in VS 2013 c# Code [duplicate]

What is the best way to unit test a method that doesn't return anything? Specifically in c#.
What I am really trying to test is a method that takes a log file and parses it for specific strings. The strings are then inserted into a database. Nothing that hasn't been done before but being VERY new to TDD I am wondering if it is possible to test this or is it something that doesn't really get tested.
If a method doesn't return anything, it's either one of the following
imperative - You're either asking the object to do something to itself.. e.g change state (without expecting any confirmation.. its assumed that it will be done)
informational - just notifying someone that something happened (without expecting action or response) respectively.
Imperative methods - you can verify if the task was actually performed. Verify if state change actually took place. e.g.
void DeductFromBalance( dAmount )
can be tested by verifying if the balance post this message is indeed less than the initial value by dAmount
Informational methods - are rare as a member of the public interface of the object... hence not normally unit-tested. However if you must, You can verify if the handling to be done on a notification takes place. e.g.
void OnAccountDebit( dAmount ) // emails account holder with info
can be tested by verifying if the email is being sent
Post more details about your actual method and people will be able to answer better.
Update: Your method is doing 2 things. I'd actually split it into two methods that can now be independently tested.
string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );
String[] can be easily verified by providing the first method with a dummy file and expected strings. The second one is slightly tricky.. you can either use a Mock (google or search stackoverflow on mocking frameworks) to mimic the DB or hit the actual DB and verify if the strings were inserted in the right location. Check this thread for some good books... I'd recomment Pragmatic Unit Testing if you're in a crunch.
In the code it would be used like
InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );
Test its side-effects. This includes:
Does it throw any exceptions? (If it should, check that it does. If it shouldn't, try some corner cases which might if you're not careful - null arguments being the most obvious thing.)
Does it play nicely with its parameters? (If they're mutable, does it mutate them when it shouldn't and vice versa?)
Does it have the right effect on the state of the object/type you're calling it on?
Of course, there's a limit to how much you can test. You generally can't test with every possible input, for example. Test pragmatically - enough to give you confidence that your code is designed appropriately and implemented correctly, and enough to act as supplemental documentation for what a caller might expect.
As always: test what the method is supposed to do!
Should it change global state (uuh, code smell!) somewhere?
Should it call into an interface?
Should it throw an exception when called with the wrong parameters?
Should it throw no exception when called with the right parameters?
Should it ...?
Try this:
[TestMethod]
public void TestSomething()
{
try
{
YourMethodCall();
Assert.IsTrue(true);
}
catch {
Assert.IsTrue(false);
}
}
Void return types / Subroutines are old news. I haven't made a Void return type (Unless I was being extremely lazy) in like 8 years (From the time of this answer, so just a bit before this question was asked).
Instead of a method like:
public void SendEmailToCustomer()
Make a method that follows Microsoft's int.TryParse() paradigm:
public bool TrySendEmailToCustomer()
Maybe there isn't any information your method needs to return for usage in the long-run, but returning the state of the method after it performs its job is a huge use to the caller.
Also, bool isn't the only state type. There are a number of times when a previously-made Subroutine could actually return three or more different states (Good, Normal, Bad, etc). In those cases, you'd just use
public StateEnum TrySendEmailToCustomer()
However, while the Try-Paradigm somewhat answers this question on how to test a void return, there are other considerations too. For example, during/after a "TDD" cycle, you would be "Refactoring" and notice you are doing two things with your method... thus breaking the "Single Responsibility Principle." So that should be taken care of first. Second, you might have idenetified a dependency... you're touching "Persistent" Data.
If you are doing the data access stuff in the method-in-question, you need to refactor into an n-tier'd or n-layer'd architecture. But we can assume that when you say "The strings are then inserted into a database", you actually mean you're calling a business logic layer or something. Ya, we'll assume that.
When your object is instantiated, you now understand that your object has dependencies. This is when you need to decide if you are going to do Dependency Injection on the Object, or on the Method. That means your Constructor or the method-in-question needs a new Parameter:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
Now that you can accept an interface of your business/data tier object, you can mock it out during Unit Tests and have no dependencies or fear of "Accidental" integration testing.
So in your live code, you pass in a REAL IBusinessDataEtc object. But in your Unit Testing, you pass in a MOCK IBusinessDataEtc object. In that Mock, you can include Non-Interface Properties like int XMethodWasCalledCount or something whose state(s) are updated when the interface methods are called.
So your Unit Test will go through your Method(s)-In-Question, perform whatever logic they have, and call one or two, or a selected set of methods in your IBusinessDataEtc object. When you do your Assertions at the end of your Unit Test you have a couple of things to test now.
The State of the "Subroutine" which is now a Try-Paradigm method.
The State of your Mock IBusinessDataEtc object.
For more information on Dependency Injection ideas on the Construction-level... as they pertain to Unit Testing... look into Builder design patterns. It adds one more interface and class for each current interface/class you have, but they are very tiny and provide HUGE functionality increases for better Unit-Testing.
You can even try it this way:
[TestMethod]
public void ReadFiles()
{
try
{
Read();
return; // indicates success
}
catch (Exception ex)
{
Assert.Fail(ex.Message);
}
}
it will have some effect on an object.... query for the result of the effect. If it has no visible effect its not worth unit testing!
Presumably the method does something, and doesn't simply return?
Assuming this is the case, then:
If it modifies the state of it's owner object, then you should test that the state changed correctly.
If it takes in some object as a parameter and modifies that object, then your should test the object is correctly modified.
If it throws exceptions is certain cases, test that those exceptions are correctly thrown.
If its behaviour varies based on the state of its own object, or some other object, preset the state and test the method has the correct Ithrough one of the three test methods above).
If youy let us know what the method does, I could be more specific.
Use Rhino Mocks to set what calls, actions and exceptions might be expected. Assuming you can mock or stub out parts of your method. Hard to know without knowing some specifics here about the method, or even context.
Depends on what it's doing. If it has parameters, pass in mocks that you could ask later on if they have been called with the right set of parameters.
What ever instance you are using to call the void method , You can just use ,Verfiy
For Example:
In My case its _Log is the instance and LogMessage is the method to be tested:
try
{
this._log.Verify(x => x.LogMessage(Logger.WillisLogLevel.Info, Logger.WillisLogger.Usage, "Created the Student with name as"), "Failure");
}
Catch
{
Assert.IsFalse(ex is Moq.MockException);
}
Is the Verify throws an exception due to failure of the method the test would Fail ?

Capturing Dialog-Windows with SpecFlow

I am fairly new to testing still, but have been using SpecFlow for a a few months. I am not entirely sure if what I am going to ask is possible, but maybe someone will have a suggestion to go about the problem.
Synopsis: My feature file makes a call to a method that creates a dialog window stored in a variable created in that method. The user would then need to fill out the dialog window (it is basically picking a file, and then clicking ok). The rest of the method relies on the information provided by the dialog window.
Problem: Since the window is created in the method and the result is stored in a variable created at that moment, I can not provide my information into the variable. But in order for my behavior tests to finish, I need to provide this information.
Example code:
Feature File:
Given I initialize the class
And I click on change selected item
Steps File:
[Given(#"I initialize the class")]
public void GivenIInitializeTheClass()
{
DoStuff();
SomeClass testClass = new SomeClasee();
}
[Given(#"IClickOnChangeSelectedItem")]
public void GivenIClickOnChangeSelectItem()
{
testClass.ChangeItem();
}
Method From Class:
public void ChangeItem()
{
var window = new SomeDialogWindow();
var result = window.ShowDialog();
if (result.HasValue && result.Value)
{
NewItem = window.SelectedItem;
}
}
I would know how to go about this if I could change the method in the class, but, in this example, I can make no changes to the class itself. Again I do not know if it is possible to assign anything to the result, or control the window since the variables for both are created within the method.
Depending on what you want to do this is quite a common pattern and fairly easy to solve, but first lets consider what kind of testing you might want to be running.
Unit tests - In a unit test that only wants to test the implementation of SomeClass we don't care about the implementation of other classes including SomeDialogWindow. Alternatively we could be writing tests that care solely about the implementation of SomeDialogWindow, or even just the implementation of SomeClass::ChangeItem and nothing else. How fine do you want to go? These tests are there to pinpoint exactly where some of your code is broken.
Acceptance tests - We build these to test how everything works together. They do care about the interaction between different units and as such will show up things that unit tests don't find. Subtle configuration issues, or more complicated interactions between units. Unfortunately they cover huge swathes of code, so leave you needing something more precise to find out what is wrong.
In a Test driven development project, we might write a single acceptance test so we can see when we are done, then we will write many unit tests one at a time, each unit test used to add a small piece of functionality to the codebase, and confirm it works before moving to the next.
Now for how to do it. As long as you are able to modify SomeClass its not a huge change, in fact all you really need is to add virtual to the ChangeItem method to make
public virtual void ChangeItem()
...
What this now allows you do is to replace the method with a different implementation when you are testing it. In the simplest form you can then declare something like,
namespace xxx.Tests
{
public class TestableSomeClass : SomeClass
{
public Item TestItem {get;set;}
public override void ChangeItem()
{
NewItem = TestItem;
}
}
}
This is a very common pattern and known as a stub. We've reduced the functionality in ChangeItem down to its bare essentials so its just a minimal stub of its original intent. We aren't testing ChangeItem anymore, just the other parts of our code.
In fact this pattern this pattern is so common there are libraries there to help us to Mock the function instead. I tend to use one called Moq and it would now look like this.
//Given
var desiredItem = ...
Mock<SomeClass> myMock = new Mock<SomeClass>();
myMock.Setup(x=>x.ChangeItem).Returns(desiredItem);
var testClass = myMock.Object;
//When
testClass.ChangeItem();
//Then
testClass.NewItem.ShouldEqual(....);
You will notice that in both these examples we have gotten rid of the GUI part of the codebase so that we can concentrate on your functionality. I would personally recommend this approach for getting 90% to get your codebase covered and end up with rapid uncomplicated testing. However sometimes you need Acceptance tests that even test the UI, and then we come to an altogether more complicated beast.
For eaxmple, your UI will include blocking calls when it displays the visual elements, such as SomeDialogWindow.ShowDialog() and these have to occur on what is commonly referred to as the UI thread. Fortunately while only one thread can be the UI thread, any thread can be the UI thread if it gets there first, but you will need to have at least one thread displaying the UI and another running the tests. You can steal a pattern from web based testing and create driver classes that control your UI, and these will end up on the test running thread performing the click operations and polling to see if the operations are complete.
If you need to go to these lengths then don't start with this as you learn how to use the testing frameworks, start with the simple stuff.

What to test/mock?

Given the following simple service class, in the GetCategories() method, should you test the fact that the categoryRepository.Query() method was called, or should you be setting up a test that keeps a list of categories and returns those?
I guess what I am saying is would mocking the categoryRepository and verifying that it's Query method was called once cover this test case?
public class CategoryService : ValidatingServiceBase, ICategoryService
{
private readonly IRepository<Category> categoryRepository;
private readonly IRepository<SubCategory> subCategoryRepository;
private readonly IValidationService validationService;
public CategoryService(
IRepository<Category> categoryRepository,
IRepository<SubCategory> subCategoryRepository,
IValidationService validationService)
: base(validationService)
{
this.categoryRepository = categoryRepository;
this.subCategoryRepository = subCategoryRepository;
this.validationService = validationService;
}
public IEnumerable<Category> GetCategories()
{
return categoryRepository.Query().ToList();
}
}
Sample Test
[Fact]
public void GetCategories_Should_CallRepositoryQuery()
{
var categoryRepo = new Mock<IRepository<Category>>();
var service = new CategoryService(categoryRepo.Object, null, null);
service.GetCategories();
categoryRepo.Verify(x => x.Query(), Times.Once());
}
It doesn't matter. In both cases (mock + behavior verification vs stub + assertion) you achieve exactly the same result and require exactly the same level of details about inner workings of class. Stick to whichever one you think is more suited in given scenario.
Unit test you posted is an example of behavior verification. You don't assert any values but instead check whether some method was called. This is especially useful when method call has no visible results (think about logging) or doesn't return any value (obviously). It of course has drawbacks, especially when you do such verification for methods that do return value, and don't check it (as is your case - we'll get to it).
The stubbing and asserting approach uses the collaborators to generate value. It doesn't check whether methods were called (at least not directly, yet such test is performed when you setup stub and that setup works), but instead relies on correct flow of stubbed value.
Let's go with simple example. Say you test a method of your class, PizzaFactory.GetPizza which looks like this:
public Pizza GetPizza()
{
var dough = doughFactory.GetDough();
var cheese = ingredientsFactory.GetCheese();
var pizza = oven.Bake(dough, cheese);
return pizza;
}
With behavior verification you'd check whether doughFactory.GetDough was called, then ingredientsFactory.GetCheese and finally oven.Bake. Had such calls indeed been made, you'd assume pizza was created. You don't check that your factory returns pizza, but assume it happens if all process' steps were completed. You can already see that drawback I mentioned earlier - I can call all the correct methods but return something else, say:
var dough = doughFactory.GetDough();
var cheese = ingredientsFactory.GetCheese();
var pizza = oven.Bake(dough, cheese);
return garbageBin.FindPizza();
Not the pizza you ordered? Notice that all the correct calls to collaborators happened just as we assumed they would.
With stub + assert approach it all looks similar except instead of verification you have stubbing. You use values generated by earlier collaborators to stub later collaborators (if somehow you get wrong dough or cheese, oven will not return pizza we wanted). The final value is what your method returns and this is what we assert:
doughFactoryStub.Setup(df => dg.GetDough).Return("thick");
ingredientsFactoryStub.Setup(if => if.GetCheese()).Return("double");
var expectedPizza = new Pizza { Name = "Margherita" };
ovenStub.Setup(o => o.Bake("thick", "double")).Return(expectedPizza);
var actualPizza = pizzaFactory.GetPizza();
Assert.That(actualPizza, Is.EqualTo(expectedPizza));
If any part of the process fails (say doughFactory returns normal dough) then the final value will be different and test will fail.
And once again, in my opinion in your example it doesn't matter which approach you use. In any normal environment both methods will verify the same thing and require same level of knowledge about your implementation. To be extra safe you might want to prefer to use the stub + assert approach in case somebody plants you a garbage bin1. But if such thing happens, unit tests are your last problem.
1 Note however that it might not be intentional (especially when complex methods are considered).
Yes, that would be the way.
mockCategoryRepository.Setup(r => r.Query()).Returns(categories)
var actualCategories = new CategoryService(mockCategoryRepository, mock..).GetCategories();
CollectionAssert.AreEquivalent(categories, actualCategories.ToList());
It would look something similar with Moq and NUnit.
What you've presented is a white-box test - an approach also possible in unit testing, but recommended only for simple methods.
In the answer presented by Sruti the service is tested in a black-box sense. The knowledge about the inner method is used only to prepare the test, but you don't verify if the method was called one time, 10 times, or wasn't called at all. Personally, I verify method calls only to verify that some external API that must be stubbed is used correctly (example: sending e-mails). Usually it is sufficient not to care about how a method works, as long as it's producing correct results.
With black-box tests the code and the tests are easier to maintain. With white-box tests, most changes of some internal structure during refactoring of a class usually must be followed by changing test code. In black-box approach you have more freedom to rearrange everything, and still be sure that interface's external behaviour hasn't changed.

"Stubbing out" a function for unit tests

I have various methods that I would like to unit test using Visual Studio's built in unit testing capability for C#. Things have been going pretty smoothly, but I've run into a scenario where I want to "stub out" a dependency on a particular function call.
Namely, I have some methods that are in the following format:
public class ClassWithMethodsIWantToUnitTest
{
public void myFcn(object someArg)
{
...
LoggerService.Instance.LogMessage("myMessage");
...
}
}
So basically, I want my unit test to simply verify that the call to "LogMessage" has occurred. I don't want to actually check a log file or anything. I want a way to see if the LoggerService line has been hit and executed.
LoggerService is a singleton, and if possible, I don't want to modify the code just for unit testing.
Based on the format of this problem, it seems to me that it should be possible to somehow take control of the code in my unit test. In other words, is there a way for me to make a fake version of LogMessage such that I can use it for my unit test? I don't want the "real" LogMessage function to be called if possible. I just want to test that the code hit the path that called the function.
Does this make any sense? Is this possible?
It certainly makes sense and is not an unknown problem.
Unfortunately you will probably need to change the code, so that it accepts dependency injection. That is, when testing you should be able to inject a specially crafted test object (a mock) instead of the real thing. In your case it probably means being able to set LoggerService.Instance to a special mock object.
The second thing you need is the fake logger instance that you will test against. You probably want a mock, which is a special object that can be set up to check behaviour of the caller. There are several mock frameworks around and I really recommend that you use one instead of trying to roll your own.
Anders' answer was definitely the "canonical" way of approaching the problem, but in .NET 4.5, there's a second option:
The Fakes framework.
It lets you add a "fakes" assembly to your unit test project that accepts a delegate to perform in place of the actual implementation of a method. Here's an example using File.ReadAllText
[TestMethod]
public void Foo()
{
using (ShimsContext.Create())
{
ShimFile.ReadAllTextString = path => "test 123";
var reverser = new TextReverser();
const string expected = "321 tset";
//Act
var actual = reverser.ReverseSomeTextFromAFile(#"C:\fakefile.txt");
//Assert
Assert.AreEqual(expected, actual);
}
}
What that test method is doing is temporarily (within the scope of the ShimsContext) replacing the implementation of File.ReadAllText with the lambda I provided. In this case, any time ReadAllText is called, it returns the string "test 123".
It's slower than regular DI, but if you're absolutely tied to a specific implementation of a singleton, it could be exactly what you need. Read more about it here.
What Anders said.
Several popular mocking frameworks are Moq and RhinoMocks
And you'd change your code so that the logger dependency was injected to your class:
public class ClassWithMethodsIWantToUnitTest
{
public ClassWithMethodsIWantToUnitTest(ILoggerService logger)
{}
public void myFcn(object someArg)
{
...
logger.LogMessage("myMessage");
...
}
}
Or something similar. A DI framework could inject the logger automatically into the class when it needs it. Esentially a DI framework automatically calls
new ClassWithMethodsIWantToUnitTest(LoggerService.Instance);

How do I unit test an implementation detail like caching

So I have a class with a method as follows:
public class SomeClass
{
...
private SomeDependency m_dependency;
public int DoStuff()
{
int result = 0;
...
int someValue = m_dependency.GrabValue();
...
return result;
}
}
And I've decided that rather than to call m_dependency.GrabValue() each time, I really want to cache the value in memory (i.e. in this class) since we're going to get the same value each time anyway (the dependency goes off and grabs some data from a table that hardly ever changes).
I've run into problems however trying to describe this new behaviour in a unit test. I've tried the following (I'm using NUnit with RhinoMocks):
[Test]
public void CacheThatValue()
{
var depend = MockRepository.GeneraMock<SomeDependency>();
depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1);
var sut = new SomeCLass(depend);
int result = sut.DoStuff();
result = sut.DoStuff();
depend.VerifyAllExpectations();
}
This however doesn't work; this test passes even without introducing any changes to the functionality. What am I doing wrong?
I see caching as orthogonal to Do(ing)Stuff. I would find a way to pull the caching logic outside of the method, either by changing SomeDependency or wrapping it somehow (I now have a cool idea for a caching class based around lambda expressions -- yum).
That way your tests for DoStuff don't need to change, you only need to make sure they work with the new wrapper. Then you can test the caching functionality of SomeDependency, or its wrapper, independently. With well-architected code putting a caching layer in place should be rather easy and neither your dependency nor your implementation should know the difference.
Unit tests shouldn't be testing implementation, they should test behavior. At the same time, the subject under test should have a narrowly-defined set of behavior.
To answer your question, you are using a Dynamic Mock and the default behavior is to allow any call that isn't configured. The additional calls are just returning "0". You need to set up an expectation that no more calls are made on the dependency:
depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1);
depend.Expect(d => d.GrabValue()).Repeat.Never();
You may need to enter record/replay mode to get it to work properly.
This seems like a case for "tests drive the design". If caching is an implementation detail of SubDependency - and therefore can't be directly tested - then probably some of its functionality (specifically, its caching behavior) needs to be exposed - and since it's not natural to expose it within SubDependency, needs to be exposed in another class (let's call it "Cache"). In Cache, of course, the behavior is contractual - public, and thereby testable.
So the tests - and the smells - are telling us we need a new class. Test-Driven Design. Ain't it great?

Categories

Resources