I am trying to use learn how to use FakeItEasy, and wanted to try using it with some data access code from an old project I have access to. While the basics of FIE seemed pretty easy, and I was able to get simple cases working, this one has me stumped.
The system used Entity Framework, and one of the data management classes handles Users, and I'm trying to figure out how to test just the basic GetUserByUserNumber function. I can use a fake IPersistenceManager<User> when instantiating the UserDataManager class, and then call the GetUserByUserNumber method, but the assertion to check that userPersistenceManager.ReadCustom was called always fails.
I've tried calling the Delete method on the fake userPersistenceManager, and the assertion for that works fine. I think it has something to do with the Linq Expression that the ReadCustom method takes as its first parameter. I just don't know how that should be handled. Any help with this would be appreciated!
This is the method in the UserDataManager that I'm trying to test:
public User GetUserByUserNumber(string userNumber, bool loadRelatedRecords = false)
{
if (string.IsNullOrWhiteSpace(userNumber))
{
throw MyAppExceptions.CreateMyAppFatalException(Constants.ExceptionKeys.Unexpected, new ArgumentNullException("userNumber"));
}
Logger.Write(string.Format("Executing GetUserByUserNumber with UserNumber {0}.", userNumber), LogCategory.General, TraceEventType.Verbose);
return _UserPersistenceManager.ReadCustom(mem => mem.UserNumber == userNumber, EntityConstants.EntityNames.UserDetail);
}
This is the IPersistenceManager method that I want to ensure is called:
TEntity ReadCustom(Expression<Func<TEntity, bool>> predicate, string includeEntityName);
This is my unit test:
[TestMethod]
public void GetUserByUserNumber_Calls_ReadCustom()
{
// Arrange
var userPersistenceManager = A.Fake<IPersistenceManager<User>>();
var dataManager = new UserDataManager(userPersistenceManager);
// Act
dataManager.GetUserByUserNumber("123456", false);
// Assert
A.CallTo(() => userPersistenceManager.ReadCustom(u => u.UserNumber == "123456", EntityConstants.EntityNames.UserDetail)).MustHaveHappened();
}
I think Tim Long's answer is essentially correct although my slant is not that this is a failing of mocking frameworks—it comes down to how easy it is (in general, not just when mocking) to determine whether two things are "the same".
The problem you have is that unless told otherwise, FakeItEasy uses .Equals to compare the arguments. Expressions don't compare well with .Equals, and so you'll get a mismatch.
One option is to explore Expression equality-checkers. There are a number of questions on StackOverflow about this already, such as How to check if two Expression<Func<T, bool>> are the same. If you can find a good way to determine the equality of the expressions, I think you could provide that method to FakeItEasy's argument matcher
(e.g. with A<Expression<Func<TEntity, bool>>.That.Matches(…)).
Alternatively, you can go Mr. Long's route and capture the argument and then interrogate it later. I suggested a similar approach just a bit ago when answering
How to fake an action<> with FakeItEasy.
In your case, you could capture the predicate and then verify its correctness by seeing how it reacts to various input objects - does it like ones with UserNumber "123456".
This seems to be an area of mocking frameworks that is very counter-intuitive and hard to use correctly. I generally shy away from doing argument matching and try to return or capture some sort of object that I can later make assertions against.
In your case, you are essentially comparing two expressions for equality. The 'look' different in the code even though they have the same syntax. I wonder, can you create those two expressions outside of the test context and see if they compare equal then?
Related
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 ?
I have come across a very strange behavior in moq and I cannot understand whether it's a bug or I am doing something wrong. Here is the example:
List<CustomerDataTransaction> transactions0 = GetTransactionsSomehow();
List<CustomerDataTransaction> transactions1 = GetTransactionsSomehow();
var portfolioTransactions0 = new List<IPortfolioTransaction>();
var portfolioTransactions1 = new List<IPortfolioTransaction>();
m_TransactionMapperMock
.Setup(m => m.CreatePortfolioTransactions(transactions0))
.Returns(portfolioTransactions0);
m_TransactionMapperMock
.Setup(m => m.CreatePortfolioTransactions(transactions1))
.Returns(portfolioTransactions1);
I have checked that transaction0 is not equal to transactions1, so it's for sure different lists. But the mock returns portfolioTransactions1 twice when called with different parameters (transactions0 and transactions1). I tried to figure out what was wrong, but I did not find any reasons. Then I have added dummy elements to each of the lists and that has fixed it, mock started to return different values as planned. Is this a bug of Mock or I don't get something? As far as I understand the values inside the list should not affect it at all.
P.S. I don't know if it's important or not but the method accepts IEnumerable<CustomerDataTransaction>
Consider trying:
It.Is<IEnumerable<CustomerDataTransaction>>(t => t == transactions1))
From memory I thought Moq used reference equality
Expanding on NinjaNye's answer, using It.Is satisfies the test is because it ensures that you are looking at the exact instance of the object, not the equality operator.
With your testing framework, if you say Assert.NotEqual and give it two objects, it uses the equality operator and says one empty list equal to the other. Think about being able to compare objectA.Property1 to objectA.Property2. It makes sense that Assert.Equal would look at the values, not the instance of the value.
Xunit provides a method Assert.Same, which will provide the same functionality as Moq's It.Is<>, verifying it is the same instance of the object. I believe that most of the popular testing frameworks today provide similar behavior.
I'm asked to write some unit tests for some functionality, but quite frankly I'm not so sure about the need or usefulness of doing so for this particular piece of code. I'm in no way trying to question the need or usefulness of unit testing in general.
The code in question is very trivial and gets used alot. Basically it's a wrapper around the .Skip() and .Take() extension methods. In my opinion the legitimacy of the methods as a whole is questionable.
The code is basically this:
public IQueryable<T> Page(IQueryable<T> query, int page, int size)
{
if(query == null) throw new ArgumentNullException("query");
if(page < 0) throw new ArgumentOutOfRangeException("page");
if(page < 0) throw new ArgumentOutOfRangeException("size");
return query.Skip(page * size).Take(size);
}
Of course I can unit test for the expected exceptions, but what else? Could very well be that I'm missing the point, so what's up with this?
You can just hand in a static collection by calling AsQueryable
List<T> dummyData = new List<T>();
//Add data
var result = Page(dummyData.AsQueryable(), 0, 10);
//Perform assertions on result.
If you are in-fact just trying to test that your pagination works correctly.
You can test quite a few things here:
Check for proper guards (the exceptions that are thrown when invalid parameters are passed).
Check that Skip was called with the correct parameter.
Check that Take was called with the correct parameter.
Check that Skip was called before Take.
Points 2 - 4 are best tested with a mock. A mocking framework comes in handy here.
This kind of testing is called "interaction-based testing".
You could also use "state-based testing" by calling the method under test with a list with data and check that the returned data is the correct subset.
A test for point 2 could look like this:
public void PageSkipsThePagesBeforeTheRequestedPage()
{
var sut = new YourClass();
var queryable = Substitute.For<IQueryable<int>>();
sut.Page(queryable, 10, 50);
queryable.Received().Skip(500);
}
This test uses NSubstitute as mocking framework.
I'm sure, there is a strong need to test this method.
First of all, because of the bug:
if(page < 0) throw new ArgumentOutOfRangeException("page");
if(page < 0) throw new ArgumentOutOfRangeException("size");
You're not checking the size variable in fact.
Anyway, there is no need to perform the "integrated" testing - you can simply mock your IQueryable object and perform the unit testing. (see this answer: How do I mock IQueryable<T>)
In my opinion, it is an absolutely right thing to do to test this method.
In fact, since IQueryable<T> may encapsulate an underlying data storage - which is the case of Entity Framework's queryables -, we're talking about integration tests.
In my case, if I'd need to test something like your piece of code, I'd store some test data in the database for later query for it.
Since I can expect the results, I can perform an assertion in order to check if the tested method returned the expected result.
UPDATE
Since I see some confusion with the downvote and some comments, I'd like to point out that I've answered this taking in account the fact that the answer is tagged as for Entity Framework and I guess that the queryable was obtained from the DbSet.
With Moq, it is possible to verify that a method is never called with certain arguments (that is, arguments satisfying certain predicates) using Times.Never.
But how to verify that, no mater how many times a method is called, it is always called with certain arguments?
The default appears to be Times.AtLeastOnce.
There is no Times.Always. Am I missing something obvious? Thanks!
Edit: I posted a suggestion to the Moq mailing list last week, but it doesn't look like it's been moderated yet. I'll post any updates here.
Edit: an example. Say I am testing a class which generates XML documents. I want to ensure that only valid documents are generated. In other words, test that the writer dependency is only ever given valid documents, with a valid sequence number, to write.
should_only_write_valid_xml_documents
Mock.Get(this.writer).Verify(
w => w.Write(
It.Is<XDocument>(doc => XsdValidator.IsValid(doc)),
It.Is<int>(n => n < 3)),
Times.Always);
And how many times is 'always?' Moq keeps track of all the times a certain method is called with certain arguments, and then uses that number for comparing to Times.Never, Times.AtLeastOnce, etc.
So, if a method is executed 4 times and you set it to 'Times.Always' what does that even mean?
Times.Never would check to make sure the number is zero.
Times.AtLeastOnce would check that the number is greater than or equal to one.
Times.Always would check that the number is.... ?
You could determine the number of times it SHOULD run programmatically, then do something like:
Times.Exactly(calculatedAmount)
But there is no way for Moq to know what 'always' means.
It sounds like you're wanting "Strict" mock behavior. If the method is called with anything other than the expected parameters, the test will fail.
This is available in Moq:
var mock = new Mock<IFoo>(MockBehavior.Strict);
(Example taken from the Moq QuickStart.)
Every invocation on the mock must now have a corresponding Setup.
Using strict mocks tends to lead to brittle tests. I would avoid this technique, or at least use it sparingly.
You can apply inversion of logic to verify ALWAYS.
E.g.:
Let's say you want to do the following verification:
mock.Verify(x => x.Method(It.Is<int>(i => i == 10)), Times.Always());
you can simply replace it with:
mock.Verify(x => x.Method(It.Is<int>(i => i != 10)), Times.Never());
My recommendation would be to create a 'fallback' matching for the method with It.IsAny conditions. You can then verify Times.Never on that matching, which should always have been superseded by the more specific match.
I just started using mock objects (using Java's mockito) in my tests recently. Needless to say, they simplified the set-up part of the tests, and along with Dependency Injection, I would argue it made the code even more robust.
However, I have found myself tripping in testing against implementation rather than specification. I ended up setting up expectations that I would argue that it's not part of the tests. In more technical terms, I will be testing the interaction between SUT (the class under test) and its collaborators, and such dependency isn't part of contract or the interface of the class!
Consider that you have the following:
When dealing with XML node, suppose that you have a method, attributeWithDefault() that returns the attribute value of the node if it's available, otherwise it would return a default value!
I would setup the test like the following:
Element e = mock(Element.class);
when(e.getAttribute("attribute")).thenReturn("what");
when(e.getAttribute("other")).thenReturn(null);
assertEquals(attributeWithDefault(e, "attribute", "default"), "what");
assertEquals(attributeWithDefault(e, "other", "default"), "default");
Well, here not only did I test that attributeWithDefault() adheres to the specification, but I also tested the implementation, as I required it to use Element.getAttribute(), instead of Element.getAttributeNode().getValue() or Element.getAttributes().getNamedItem().getNodeValue(), etc.
I assume that I am going about it in the wrong way, so any tips on how I can improve my usage of mocks and best practices will be appreciated.
EDIT:
What's wrong with the test
I made the assumption above that the test is a bad style, here is my rationale.
The specification doesn't specify which method gets called. A client of the library shouldn't care of how attribute is retrieved for example, as long as it is done rightly. The implementor should have free reign to access any of the alternative approaches, in any way he sees fit (with respect to performance, consistency, etc). It's the specification of Element that ensures that all these approaches return identical values.
It doesn't make sense to re-factor Element into a single method interface with getElement() (Go is quite nice about this actually). For ease of use, a client of the method should be able to just to use the standard Element in the standard library. Having interfaces and new classes is just plain silly, IMHO, as it makes the client code ugly, and it's not worth it.
Assuming the spec stays as is and the test stays as is, a new developer may decide to refactor the code to use a different approach of using the state, and cause the test to fail! Well, a test failing when the actual implementation adheres to the specification is valid.
Having a collaborator expose state in multiple format is quite common. A specification and the test shouldn't depend on which particular approach is taken; only the implementation should!
This is a common issue in mock testing, and the general mantra to get away from this is:
Only mock types you own.
Here if you want to mock collaboration with an XML parser (not necessarily needed, honestly, as a small test XML should work just fine in a unit context) then that XML parser should be behind an interface or class that you own that will deal with the messy details of which method on the third party API you need to call. The main point is that it has a method that gets an attribute from an element. Mock that method. This separates implementation from design. The real implementation would have a real unit test that actually tests you get a successful element from a real object.
Mocks can be a nice way of saving boilerplate setup code (acting essentially as Stubs), but that isn't their core purpose in terms of driving design. Mocks are testing behavior (as opposed to state) and are not Stubs.
I should add that when you use Mocks as stubs, they look like your code. Any stub has to make assumptions about how you are going to call it that are tied to your implementation. That is normal. Where it is a problem is if that is driving your design in bad ways.
When designing unit tests you will always effectively test your implementation, and not some abstract specification. Or one can argue that you will test the "technical specification", which is the business specification extended with technical details. There is nothing wrong with this. Instead of testing that:
My method will return a value if defined or a default.
you are testing:
My method will return a value if defined or a default provided that the xml Element supplied will return this attribute when I call getAttribute(name).
The only solution I can see for you here (and I have to admit I'm not familiar with the library you're using) is to create a mock element that has all of the functionality included, that is, also have the ability to set the value of getAttributeNote().getValue() and getAttributes().getNamedItem().getNodeValue().
But, assuming they're all equivalent, it's fine to just test one. It's when it varies that you need to test all cases.
I don't find anything wrong with your use of the mocks. What you are testing is the attributeWithDefault() method and it's implementation, not whether Element is correct or not. So you mocked Element in order to reduce the amount of setup required. The test ensures that the implementation of attributeWithDefault() fits the specification, naturally there needs to be some specific implementation that can be run for the test.
You're effectively testing your mock object here.
If you want to test the attributeWithDefault() method, you must assert that e.getAttribute() gets called with the expected argument and forget about the return value. This return value only verifies the setup of your mock object.
(I don't know how this is exactly done with Java's mockito, I'm a pure C# guy...)
It depends on whether getting the attribute via calling getAttribute() is part of the specification, or if it is an implementation detail that might change.
If Element is an interface, than stating that you should use 'getAttribute' to get the attribute is probably part of the interface. So your test is fine.
If Element is a concrete class, but attributeWithDefault should not be aware of how you can get the attribute, than maybe there is a interface waiting to appear here.
public interface AttributeProvider {
// Might return null
public String getAttribute(String name);
}
public class Element implements AttributeProvider {
public String getAttribute(String name) {
return getAttributeHolder().doSomethingReallyTricky().toString();
}
}
public class Whatever {
public String attributeWithDefault(AttributeProvider p, String name, String default) {
String res = p.getAtribute(name);
if (res == null) {
return default;
}
}
}
You would then test attributeWithDefault against a Mock AttributeProvider instead of an Element.
Of course in this situation it would probably be an overkill, and your test is probably just fine even with an implementation (You will have to test it somewhere anyway ;) ). However this kind of decoupling might be usefull if the logic ever goes any more complicated, either in getAttribute or in attributeWithDefualt.
Hoping this helps.
It seems to me that there are 3 things you want to verify with this method:
It gets the attribute from the right place (Element.getAttribute())
If the attribute is not null, it is returned
If the attribute is null, the string "default" is returned
You're currently verifying #2 and #3, but not #1. With mockito, you could verify #1 by adding
verify(e.getAttribute("attribute"));
verify(e.getAttribute("other"));
Which ensures that the methods are actually getting called on your mock. Admittedly this is a little clunky in mockito. In easymock, you'd do something like:
expect(e.getAttribute("attribute")).andReturn("what");
expect(e.getAttribute("default")).andReturn(null);
It has the same effect, but I think makes your test a bit easier to read.
If you are using dependency injection then the collaborators should be part of the contract. You need to be able to inject all collaborators in through the constructor or a public property.
Bottom line: if you have a collaborator that you newing up instead of injecting then you probably need to refactor the code. This is a change of mindset necessary for testing/mocking/injecting.
This is a late answer, but it takes a different viewpoint from the other ones.
Basically, the OP is right in thinking the test with mocking is bad, for the reasons he stated in the question. Those saying that mocks are ok have not provided good reasons for it, IMO.
Here is a complete version of the test, in two versions: one with mocking (the BAD one) and another without (the GOOD one). (I took the liberty of using a different mocking library, but that doesn't change the point.)
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.junit.*;
import static org.junit.Assert.*;
import mockit.*;
public final class XmlTest
{
// The code under test, embedded here for convenience.
public static final class XmlReader
{
public String attributeWithDefault(
Element xmlElement, String attributeName, String defaultValue
) {
String attributeValue = xmlElement.getAttribute(attributeName);
return attributeValue == null || attributeValue.isEmpty() ?
defaultValue : attributeValue;
}
}
#Tested XmlReader xmlReader;
// This test is bad because:
// 1) it depends on HOW the method under test is implemented
// (specifically, that it calls Element#getAttribute and not some other method
// such as Element#getAttributeNode) - it's therefore refactoring-UNSAFE;
// 2) it depends on the use of a mocking API, always a complex beast which takes
// time to master;
// 3) use of mocking can easily end up in mock behavior that is not real, as
// actually occurred here (specifically, the test records Element#getAttribute
// as returning null, which it would never return according to its API
// documentation - instead, an empty string would be returned).
#Test
public void readAttributeWithDefault_BAD_version(#Mocked final Element e) {
new Expectations() {{
e.getAttribute("attribute"); result = "what";
// This is a bug in the test (and in the CUT), since Element#getAttribute
// never returns null for real.
e.getAttribute("other"); result = null;
}};
String actualValue = xmlReader.attributeWithDefault(e, "attribute", "default");
String defaultValue = xmlReader.attributeWithDefault(e, "other", "default");
assertEquals(actualValue, "what");
assertEquals(defaultValue, "default");
}
// This test is better because:
// 1) it does not depend on how the method under test is implemented, being
// refactoring-SAFE;
// 2) it does not require mastery of a mocking API and its inevitable intricacies;
// 3) it depends only on reusable test code which is fully under the control of the
// developer(s).
#Test
public void readAttributeWithDefault_GOOD_version() {
Element e = getXmlElementWithAttribute("what");
String actualValue = xmlReader.attributeWithDefault(e, "attribute", "default");
String defaultValue = xmlReader.attributeWithDefault(e, "other", "default");
assertEquals(actualValue, "what");
assertEquals(defaultValue, "default");
}
// Creates a suitable XML document, or reads one from an XML file/string;
// either way, in practice this code would be reused in several tests.
Element getXmlElementWithAttribute(String attributeValue) {
DocumentBuilder dom;
try { dom = DocumentBuilderFactory.newInstance().newDocumentBuilder(); }
catch (ParserConfigurationException e) { throw new RuntimeException(e); }
Element e = dom.newDocument().createElement("tag");
e.setAttribute("attribute", attributeValue);
return e;
}
}