I'm unit testing my C# application that Parses a CSV. I'm at 94% code coverage, because I can't force it to fail the try/catch blocks... I'm using CsvHelper from Nuget http://joshclose.github.io/CsvHelper
public void ParseCsv([FromBody] string csvText)
{
var parseCsv = new XsvData(new[] { "\t", "," });
try
{
using (var reader = new XsvReader(new StringReader(csvText)))
{
parseCsv.Read(reader, headerExists: true);
}
}
catch (Exception)
{
var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("Unable to read CSV."),
ReasonPhrase = "Invalid CSV"
};
throw new HttpResponseException(response);
}
}
I've tried passing the most obscure strings I could think of to it, but it makes it through this, and errors out later on in the function..
[TestMethod]
//[ExpectedException(typeof(HttpResponseException))]
public void TestUploadCsv_UploadingCsvNonCsv()
{
const string csvText = "fhfhk#- jhjfh#ajh- fjkqeqir%hjewq#hf- ujewqh$phfuw \n hfwu- ihfq&if*u#q- afuhwu- fhiue#wfhiuewhiuf";
var context = GetMyFakeEntityDatabase();
var controller = new MyController(context);
controller.ParseCsv(csvText);
}
After the try/catch blocks, I have a section that enforces all the headers exist, and it fails there, but it should be failing during the reading, for this example. How do I force my unit test to fail? Any help is appreciated! Thanks in advance.
Use the Provider Pattern and interfaces instead of concrete types, then run your unit tests by substituting mock objects that will throw the exceptions.
In detail:
Extract Interface IXsvReader from XsvReader
Implement a new concrete instance of IXsvReader that throws exceptions on Read. Create one concrete implementation class for each error you expect to handle separately (in this case, you only need one).
In the class that contains the ParseCSV method, have a property for an IXsvProvider that is settable. In the constructor for that same class, set that property to a default provider that will return a "real" reader. This interface has only one method, GetXsvReader(string text)
In your test class, new up the class with the ParseCSV function, then inject an IXsvProvider(s) that returns your "dummy" IXsvReader that simply throws exceptions whenever you try to use the method.
You should use Inversion of Control and inject the dependency into the controller instead of creating it in controller action. This way you can mock out the reader, and have it throw an except instead.
I'm going to write this example in terms of CsvHelper since that's what you say you are using, even though the example doesn't look like it.
Roughly:
public class MyController : Controller
{
private readonly ICsvReader csv;
public MyController( ICsvReader csv )
{
this.csv = csv;
}
}
public class CsvReaderMock : ICsvReader
{
public void Read()
{
throw new Exception();
}
}
Now you can use your mock ICsvReader when testing, and it will throw an exception.
Also, you should only ever test a single method. If your method has dependencies, you should be passing them in instead of creating them, so you can test only the code in that method, and not of the classes it creates.
I solved this by just passing it null, like juharr recommended in the comments.
Related
I am using Moq to write test cases and when I try to assign the mock function within the constructor it comes up with the error saying that I cannot assign it because the target method is a group method however there is only one method defined.
I have written an interface etc. as follows:
...
public interface IRSPPortal
{
string GetOrderStatus(OrderInfo OrderNum);
}
public class RSPPortal : IRSPPortal
{
public RSPPortal(IRSPPortal GetOrderStatusMock)
{
this.GetOrderStatus = GetOrderStatusMock; //This line gives the error
}
public string GetOrderStatus(OrderInfo OrderNum)
{
//stuff done here to access a database
}
}
...
There is only one method GetOrderStatus(OrderInfo OrderNum) so I don't know why it has classified it as a method group. What is the simplest way to overcome this error?
I have tried to use
this.GetOrderStatus = GetOrderStatusMock.GetOrderStatus;
but that didn't work either.
Thanks everyone.
That's not how Moq works. If you want to mock IRSPPortal:
Mock<IRSPPortal> rspPortalMock = new Mock<IRSPPortal>();
rspPortalMock.Setup(a => a.GetOrderStatus(It.IsAny<OrderInfo>())).Returns(<string you want returned from the mocked method>);
Now you have a mock of IRSPPortal that will return whatever string you want from GetOrderStatus.
To use that mocked object just pass in rspPortalMock.Object to whatever class is using IRSPPortal.
I understand that you can unit test a void method by checking for its effects. However, looking at the loadConfigFile method in this code:
internal XmlDocument configData;
public ConfigFile()
{
configData = new XmlDocument();
}
/// <summary>
/// Load config file into memory
/// </summary>
/// <param name="filename">path and filename of config file</param>
public void loadConfigFile(string filename)
{
if(string.IsNullOrEmpty(filename))
throw new System.ArgumentException("You must specify a filename");
try
{
configData.Load(filename);
}
catch(Exception ex)
{
throw new Exception("Config file could not be loaded",ex);
}
}
It loads a config file into a private field - which needs to be kept private so that developers do not modify the value directly. Instead the modification will be done through setConfigValue and getConfigValue methods (which I would assume need to be tested separately).
Given this, how would I test that the loadConfigFile actually worked? As I cant access the private configData field.
Where else in that class is configData used?
If, say, you have a method like
public string GetValue()
{
return configData.GetsomeDataFromThis;
}
Then I suggest you have a test like so:
public void ReadValueFromLoadedConfigData()
{
// Arrange.
const string ExpectedValue = "Whatever";
var sut = new ConfigFile();
sut.loadConfigFile(#"C:\PathToTheConfigFile");
// Act.
string actual = sut.GetConfigValue();
// Assert.
Assert.AreEqual(ExpectedValue, actual);
}
In your tests, try to test only the public interactions, since going deep into the class, by having to read values of private fields, means your class isn't test friendly.
You could test that getConfigValue returned the values loaded from the file, basically.
Just because you test setConfigValue/getConfigValue in other tests doesn't mean that you can't use them in the test for loadConfigFile.
As an aside, I'd strongly urge you to follow .NET naming conventions, starting your method names with capital letters. (I'd also urge you to make your field private rather than internal...)
A unit test is basically a way to say "given this input, verify that this happened", it is not a substitute for verifying that your application is in a valid state.
In the example, the loadConfigFile method throws an exception if the precondition is not met, or the load operation failed. This will then be detected in the unit test, which will fail.
If any other validation is needed on the config beyond that no exception is thrown, that should be handled in the class itself.
So basically, I have an abstract class which has a unique, incremental ID - Primitive. When a Primitive (or more precisely, an inheritor of Primitive) is instantiated, the ID is incremented - up to the point where the ID overflows - at which point, I add a message to the exception and rethrow.
OK, that all works fine... but I'm trying to test this functionality and I've never used mocking before. I just need to make enough Primitives for the ID to overflow and assert that it throws at the right time.
It is unreasonable to instantiate 2 billion objects to do this! However I don't see another way.
I don't know if I'm using mocking correctly? (I'm using Moq.)
Here's my test (xUnit):
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
for (; ; )
{
var mock = new Mock<Primitive>();
}
});
}
and:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive()
{
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
I assume I'm doing it wrong - so how do I test this properly?
You don't need mocking for this. You use mocking when two classes work together and you want to replace one class with a mock (fake) one so you only have to test the other one. This is not the case in your example.
There is however a way you could use mocks, and that fixes your issue with the 2bln instances. If you separate the ID generation from the Primitive class and use a generator, you can mock the generator. An example:
I've changed Primitive to use a provided generator. In this case it's set to a static variable, and there are better ways, but as an example:
public abstract class Primitive
{
internal static IPrimitiveIDGenerator Generator;
protected Primitive()
{
Id = Generator.GetNext();
}
internal int Id { get; private set; }
}
public interface IPrimitiveIDGenerator
{
int GetNext();
}
public class PrimitiveIDGenerator : IPrimitiveIDGenerator
{
private int? _previousId;
public int GetNext()
{
try
{
_previousId = checked(++_previousId) ?? 0;
return _previousId.Value;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
Then, your test case becomes:
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
var generator = new PrimitiveIDGenerator();
for (; ; )
{
generator.GetNext();
}
});
}
This will run a lot faster and now you're only testing whether the ID generator works.
Now, when you e.g. want to test that creating a new primitive actually asks for the ID, you could try the following:
public void Does_primitive_ask_for_an_ID()
{
var generator = new Mock<IPrimitiveIDGenerator>();
// Set the expectations on the mock so that it checks that
// GetNext is called. How depends on what mock framework you're using.
Primitive.Generator = generator;
new ChildOfPrimitive();
}
Now you have separated the different concerns and can test them separately.
The point of the mock is to simulate an external resource. It's not what you want, you want to test your object, no mock needed in this szenario. Just instantiate the 2 billion objects if you like to, it doesn't hurt since the GC will throw away the old instances (but may take a while to complete).
Id' actually add another constructor which accepts a strarting value for the identity counter, so that you can actually start close to int.MaxValue and therefore don't need to instatiate as many objects.
Also, just from readin the source I can tell that your object will fail the test. ;-)
You have two problems baked into this question:
How to unit test an abstract class, that you can't instantiate.
How to efficiently unit test functionality that requires two billion instances to be created and destroyed.
I think the solutions are pretty simple, even though you'll have to re-think the structure of your object slightly.
For the first problem, the solution is as simple as adding a fake that inherits Primitive, but adds no functionality, to your test project. You can then instantiate your fake class instead, and you'll still be testing the functionality of Primitive.
public class Fake : Primitive { }
// and in your test...
Assert.Throws(typeof(OverflowException), delegate() { var f = new Fake(int.MaxValue); });
For the second problem, I'd add a constructor that takes an int for the previous ID, and use constructor chaining to "not need it" in your actual code. (But how to you get to know of the previous id otherwise? Can't you set that to int.MaxValue-1 in the setup of your test?) Think of it as dependecy injection, but you're not injecting anything complex; you're just injecting a simple int. It could be something along these lines:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive() : Primitive([some way you get your previous id now...])
protected Primitive(int previousId)
{
_previousId = previousId;
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
All has been said in the other answers. I just want to show you an alternative, maybe this is somehow interesting for you.
If you made the _previousId field of your Primitive class internal (and included the respective InternalsVisibleTo attribute, of course), then your test could be as simple as this with the Typemock Isolator tool:
[Fact(DisplayName = "Test Primitive count limit"), Isolated]
public void TestPrimitiveCountLimit()
{
Primitive._previousId = int.MaxValue;
Assert.Throws<OverflowException>(() =>
Isolate.Fake.Instance<Primitive>(Members.CallOriginal, ConstructorWillBe.Called));
}
Sure, Typemock comes with some license costs, but it definitely makes life much easier and saves you a lot of time, if you have to write large amounts of test code - especially on systems which are not easily tested or are even impossible to test with a free mocking framework.
Thomas
I'm new to mocking/testing and wanting to know what level should you go to when testing. For example in my code I have the following object:
public class RuleViolation
{
public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }
public RuleViolation( string errorMessage )
{
ErrorMessage = errorMessage;
}
public RuleViolation( string errorMessage, string propertyName )
{
ErrorMessage = errorMessage;
PropertyName = propertyName;
}
}
This is a relatively simple object. So my question is:
Does it need a unit test?
If it does what do I test and how?
Thanks
it doesn't contain any logic => nothing to test
I would say probably not. The only thing that you would probably want to verify if it is extremely important are the access modifiers:
public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }
If it is really really important that code outside the class cannot modify them that might be the only thing I would try and verify.
Here is how you can get the accessors in a property:
class Program
{
static void Main(string[] args)
{
var property = typeof(Test).GetProperty("Accessor");
var methods = property.GetAccessors();
}
}
public class Test
{
public string Accessor
{
get;
private set;
}
}
With the property.GetAccessors();
You can see if the setter is there. If it is, then the setter is public. (There is also properties IsPrivate and IsPublic you can use to verify the other Accessors as well).
If it were my code and my object I would have tests for it, no matter how simple or complicated the class is, period. Even if the class seems unlikely to break, tests are where, IMO, you document your assumptions, design decisions, and proper usage.
By doing so, you not only validate that what you have works as intended, but you have the opportunity to think through typical scenarios (what happens if the ctor params are null or empty or have white space at the end? Why is the PropertyName optional in an immutable class?).
And IF (when?) requirements change you have a solid starting point for addressing that. And IF this trivial class somehow doesn't interact nicely with all of the other classes, you may have a test to catch that before your customers do.
It's just the right way to engineer your code.
HTH,
Berryl
You could unit test this object, but it's so simple as to not require it. The test would be something like (NUnit example)
[Test]
public void TestRuleViolationConstructorWithErrorMessageParameterSetsErrorMessageProperty() {
// Arrange
var errorMessage = "An error message";
// Act
var ruleViolation = new RuleViolation(errorMessage);
// Assert
Assert.AreEqual(errorMessage, ruleViolation.ErrorMessage);
}
There's little value to writing tests like these, however, as you are testing that the .NET framework's properties work correctly. Generally you can trust Microsoft to have got this right :-)
Regarding mocking, this is useful when your class under test has a dependency, perhaps on another class in your own application, or on a type from a framework. Mocking frameworks allow you call methods and properties on the dependecy without going to the trouble of building the dependency concretely in code, and instead allow you to inject defined values for properties, return values for methods, etc. Moq is an excellent framework, and a test for a basic class with dependency would look something like this:
[Test]
public void TestCalculateReturnsBasicRateTaxForMiddleIncome() {
// Arrange
// TaxPolicy is a dependency that we need to manipulate.
var policy = new Mock<TaxPolicy>();
bar.Setup(x => x.BasicRate.Returns(0.22d));
var taxCalculator = new TaxCalculator();
// Act
// Calculate takes a TaxPolicy and an annual income.
var result = taxCalculator.Calculate(policy.Object, 25000);
// Assert
// Basic Rate tax is 22%, which is 5500 of 25000.
Assert.AreEqual(5500, result);
}
TaxPolicy would be unit tested in its own fixture to verify that it behaves correctly. Here, we want to test that the TaxCalculator works correctly, and so we mock the TaxPolicy object to make our tests simpler; in so doing, we can specify the behaviour of just the bits of TaxPolicy in which we're interested. Without it, we would need to create hand-rolled mocks/stubs/fakes, or create real instances of TaxPolicy to pass around.
There's waaaaay more to Moq than this, however; check out the quick-start tutorial to see more of what it can do.
Even if simple, there's logic in your constructors. I would test that:
RuleViolation ruleViolation = new RuleViolation("This is the error message");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.IsEmpty(ruleViolation.PropertyName);
RuleViolation ruleViolation = new RuleViolation("This is the error message", "ThisIsMyProperty");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.AreEqual("ThisIsMyProperty", ruleViolation.PropertyName);
I want to create an error class. And it has some static properties. For example : Message, InnerException, Stacktrace, Source. But I want to add some dynamic properties.
If exception is a FileNotFoundException, I want to add FileName property.
Or if it is a SqlException, I want to add LineNumber property. And I can't inherit that class from Exception because, I return that class from a web service. How can I do that?
C# is a statically typed language. This means you generally cannot dynamically add properties to classes at run-time without some really funky IL injection (which you definitely want to avoid).
In your case it seems that you need to understand exceptions a bit better - we usually throw a specific type of exception to indicate the cause of an exceptional problem. For example, if you are looking for a file and it's not there you would throw a FileNotFoundException or if there is some application-specific problem you could create your own exception class and throw that exception.
Keep in mind that exceptions should be exceptional.
Instead of trying to do something C# currently doesn't handle very well, I suggest you take a somewhat different approach.
Why don't you add those extra properties as data in a dictionary? Your class could expose an interface to get a number of "properties" (in the general sense of the word), i.e. the keys and your calling code could then examine these and use them to look up values as necessary.
you can create type dynamically using new features in C# like anonymous types
I am not sure if you are trying to do some thing similar, but can achieve the requirement as follows
public interface IError { }
public class ErrorTypeA : IError
{ public string Name; }
public class ErrorTypeB : IError
{
public string Name;
public int line;
}
public void CreateErrorObject()
{
IError error;
if (FileNotFoundException) // put your check here
{
error = new ErrorTypeA
{
Name = ""
};
}
elseif (InValidOpertionException) // put your check here
{
error = new ErrorTypeB
{
Name = "",
line = 1
};
}
}
Hope this helps
My take on this would be to use a dictionary where you can store all extra data.
public class Logging
{
private Dictionary<string, string> _ExtraInfo = new Dictionary<string, string>();
public Dictionary<string, string> ExtraInfo {
get { return _ExtraInfo; }
set { _ExtraInfo = value; }
}
}
To use:
Logging MyLogger = new Logging();
MyLogger.ExtraInfo.Add("Filename", thefilename);
MyLogger.ExtraInfo.Add("ClientTime", now);
And so on.
It's very unclear what you're trying to achieve. Reconsider your design in favor of non-static classes and use inheritance.
And you do remember that there are lots of ready-made exception classes in the .NET BCL, right?
Create a new exception type, derived from Exception. Throw this exception, and set the InnerException property to the exception that caused all the ruckus.
You can check for the type of the inner exception and display data accordingly.
If possible, you could of course also just throw the original excpetion to have the caller handling it.