Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have a method which calls another a method from another class which in turn executes numerous private methods within the second class. One method writes a file which is then picked up by an external process, the external process runs between 5 to 30 mins depending on what needs processed, another file is then produced which is picked up by my application which reads it and returns data into the initial method which was called.
I know what I described is not a "Unit" but the method is public, so my question is what would I need to test in this method and how could I mock the call to the method within the second class? Or do I just let the method run normally whether it be 5 mins or 30 mins?
class A
{
public List<DataClass> MethodUnderTest()
{
List<string> requiredData;
SecondClass B = New SecondClass();
requiredData = B.GenerateFile();
//B.GenerateFile() Executes a number of private methods within the SecondClass,
//This can be treated as a service call. This runs between 5 and 30 mins
return requiredData.Select(r => new DataClass{
Property1 = r.Substring(0,2),
Property2 = r.Substring(3,5),
Property3 = r.Substring(9,10)
}).ToList();
}
}
Treat SecondClass as 3rd party dependency and encapsulate it behind code you control. Create an abstraction of the functionality you want from the dependency;
public interface ISecondClass {
List<string> GenerateFile();
}
Class A also has too many concerns and should remove any responsibilities/concerns that do not belong to class A.
public interface IDataClassParser {
DataClass Parse(string data);
}
public class DefaultDataClassParser : IDataClassParser {
public DataClass Parse(string data) {
return new DataClass {
Property1 = data.Substring(0, 2),
Property2 = data.Substring(3, 5),
Property3 = data.Substring(9, 10)
};
}
}
The above is a naive example for demonstration purposes.
Refactor the target class to now explicitly depend on the abstraction and not on the concretion.
public class A {
private readonly ISecondClass B;
private readonly IDataClassParser parser;
public A(ISecondClass B, IDataClassParser parser) {
this.B = B;
this.parser = parser;
}
public List<DataClass> MethodUnderTest() {
List<string> requiredData = B.GenerateFile();
return requiredData.Select(createNewDataClass).ToList();
}
private DataClass createNewDataClass(string r) {
return parser.Parse(r);
}
}
Class A is no longer tightly coupled to implementation concerns and now the method under test can be tested in isolation.
Example test
[TestClass]
public class ATest {
[TestMethod]
public void MethodUnderTest_Should_Return_DataClassList() {
//Arrange
List<string> mockData = new List<string>();
//TODO: Populate mockData
var mockB = new Mock<ISecondClass>();
mockB.Setup(_ => _.GenerateFile()).Returns(mockData);
var sut = new A(mockB.Object, new DefaultDataClassParser());
//Act
var actual = sut.MethodUnderTest();
//Assert
//TODO: assert that the actual result satisfies expectations
}
}
Technically the above is now only actually testing the parser and thus an additional test can be written to test the parsing code in isolation.
[TestClass]
public class DataClassParserTest {
[TestMethod]
public void DataClassParser_Should_Return_DataClass() {
//Arrange
string mockData = "..."; //TODO: Populate mockData
var sut = new DefaultDataClassParser();
//Act
var actual = sut.Parse(mockData);
//Assert
//TODO: assert that the actual result satisfies expectations
}
}
Finally, in production, the implementation of your long running class would derive from the abstraction and encapsulate the dependent SecondClass
public class SecondClassWrapper : ISecondClass {
private SecondClass B = new SecondClass();
public List<string> GenerateFile() {
return B.GenerateFile();
}
}
I think you kind of answered your own question, but I will outline what I would do: Create a interface for SecondClass and depend on that (you will need to inject that dependency (any way you like)), then I would mock its behavior in the unit tests. For that moq would do the job. That levs us with what logic to test: well the only interesting thin going on is the substring stuff - so test that. Then you will need to visit the SecondClass and see what unit test you can create there.
What about unit and non unit test? I say you need both, but you will execute them different (where unit should be run every time you change the code on your machine (so, they need to execute fast (hence mock is key here) like a few k in ms), and the integration/functional tests that will execute all dependencies on commit (normally on a build server). And they will take more time (in your case at least 30s to a few m) but that is fine since they do not run as often.
You're trying to determine how to unit test a method of a class (A) that invokes a method of another class (SecondClass). The method that you're testing doesn't do much. For the most part it will work if the the method it invokes works. So that (GenerateFile) is the best place to focus on writing tests.
You mentioned that SecondClass invokes a number of private methods. How complex are those methods? I'm guessing (and I could be way off) that some of them are rather complex because the method that calls them takes so long to run. If the small tasks that make up that long-running process is tested then your process is a composition of tested methods or classes.
If those private methods are complex then you can't really test them by testing a method that calls a method that calls those methods. Perhaps some of the behavior of those private methods can be placed in separate classes, which can themselves be unit tested.
It sounds like a lot of moving things around, but in order to get the benefit of testing we have to write code which can be tested. That changes the way we write code, and usually for the better.
Going back to the method you originally asked about:
You have a method that takes a List<string> and converts it to a List<DataClass>. For simplicity, why not write a method that converts a string to a DataClass? Perhaps you could put that in an extension or even in its own class.
DataClass FromString(string input)
{
return new DataClass{
Property1 = r.Substring(0,2),
Property2 = r.Substring(3,5),
Property3 = r.Substring(9,10)
}
}
Then you can test that method to make sure that a DataClass parsed from a string has the expected property values. And your previous statement becomes so simple that it hardly even needs a test of its own.
return requiredData.Select(r => FromString(r)).ToList();
As was suggested in another answer, SecondClass should ideally be an interface on which A depends. But even if it's not, if SecondClass is itself unit tested well then MethodUnderTest is going to be sound because it's doing nothing except calling one tested method and passing the result to another tested method.
But if you do replace SecondClass with an interface then MethodUnderTest becomes super easy to test because you just use a "test double", a simple implementation for test purposes only that's hard coded to return the values that you want to test. So your test is effectively saying, "Assuming that ISecondClass returns these values, I expect MethodUnderTest to return these values." And it won't take minutes to run, only milliseconds.
Even if all of the pieces are tested, it makes sense that you'd still want an integration test that runs the whole thing end-to-end. Can you create a small file with less data and run your test against that?
Related
In Nunit I try to test a method. I prepared the same input as in production code, but still method which do my work doesn't call properly. Tried to mock it, with no effect at this moment.
I was told that moq is the answer and it won't be easy, but send me a "Similar" question from this forum. below is try of all that I could. all found in that topic was implemented, but service is still not called properly. Checked if in normal case it would work (program.cs) and there function is called, and works as it should.
public class Helper
{
public string a;
public string b;
public Helper(string aa, string bb)
{
a = aa;
b = bb; //here is some transformation, but I checked it, and it's working properly
}
}
public class Service
{
public static string NotWorkingFunction(Helper o)
{
InternallService w = ThatPrivateFunctionWorks(o);
return ThatPrivateFunctionDont(w);
}
private InternallService ThatPrivateFunctionWorks(Helper o)
{
return DLL_external.SomeInternalService(o); //call was ok in both program, and in NUnit
}
ThatPrivateFunctionDont(InternallService w)
{
return DLL_external.CallingServiceFarAwayFromDLL(w); //this one works if is in part of program, but does not from NUnit. checks if have permission from Windows Credentials, then do a work. Error here from NUnit is that he cannot even call this function!
}
}
public class InternallService
{
public string smth;
public InternallService(Helper o)
{
smth = o.a;
}
}
public class DLL_external
{
public InternallService SomeInternalService(Helper o)
{
InternallService p = new InternallService(o);
return p; //prepare service for function. does not need to connect. output also is checked n another way, and is ok.
}
public InternallService CallingServiceFarAwayFromDLL(InternallService o)
{
return o; //here it connects to the service (don't know how, which protocol etc. works if run under program.cs)
}
}
in Nunit
public class Test
{
[Test]
public void Tester()
{
Mock<Helper> MockedObject = new Mock<Helper>("a", "B"); //Mocking an object
Mock<Service> MockedService = new Mock<Service>(MockBehavior.Strict);
var Helper = new Helper("a", "B");
Service.NotWorkingFunction(MockedObject.Object); //still does not work properly. cannot call service inside the function (But very similar thing Can, but in Program.cs)
MockedService.Object.NotWorkingFunction(MockedObject.Object);//service does not call
MockedService.Setup(p => p.NotWorkingFunction(MockedObject.Object)); //found at Stack overflow, but still function is not called
//of course all uncompiling things are commented in mine code
}
}
Expected to work. but still don't know how call it to test from NUnit. Maybe I am wrong with tool, which I use.
The idea of unit testing is that you test individual units of code rather than the whole system. Integration testing is where you test the whole system. You should test each public interface of each class individually. If that class has dependencies that you want to exclude from the test, you can create mocks of those dependencies: these are fake objects that are called instead of calling your actual code.
For example, to test the function that you say is not working you write a test that calls that function, not a test that goes through the rest of the code to hopefully call that function. You need to set up the data the function being tested needs, either directly or with mock objects. So tests for Dll_External might start like this:
[TestFixture]
public class Dll_External_Tests
{
[Test]
public void ShouldReturnAnInternalServiceFromCallingServiceFarAwayFromDLL()
{
// setup
Helper helper = new Helper("a", "B");
InternallService internalService = new InternallService(helper);
DLL_external dLL_external = new DLL_external();
// act
var result = dLL_external.CallingServiceFarAwayFromDLL(internalService);
// assert
Assert.IsNotNull(result);
Assert.IsTrue(result is InternallService);
// add more assertions for what you expect the result to be
}
}
You will see this test does not use Service at all - it is only testing DLL_External and only creates the objects it needs to be able to do that.
Incidentally, the code you have shown won't compile: you need an object to call a method on. You can only call static methods directly on the class like ClassName.StaticMethod(). Also, it can be a bit confusing if your objects have the same name as the class, convention is that class names start with a capital letter and instances (objects) start with a lower case letter.
I am currently writing unit tests for a class that formats values based on parameters found in a big xml file.
The class I am testing receives another class in its constructor that provides functionality to parse and read the xml files. I think it is bad style to give the tested class a concrete instance of the xml reading class, because I believe doing so would result in testing the xml reading class every time I want to - in fact - test the formatting functions of the main class. All unit tests in the formatting class would fail if there was a problem in the xml reading class, which is clearly not the formatting class' fault.
So how should I proceed?
Obviously I would just create a mock of the xml reading class and pass that as an argument to the constructor. However the formatting class would use this instance to create about 5 private instances of other classes.
Because I don't know what these classes want to do (and honestly these tests should not care) I would like to mock away these private fields of the class I am testing.
Is that even ok to do? How would I do that using Moq?
-edit-
see the following example:
public class FormatterCore : IFormatterInterfaceIWantToTest
{
public FormatterCore(IConfigService service)
{
this.something = new SomeStuffA(service);
this.somethingThatINeed = new SomethingUserfull(service);
this.somethingElse = new SomeOtherStuff(service);
this.somethingTotallyDifferent = new SomeReallyUselessStuff(service);
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
In my example I want to test the method Format<T>() of the interface. To create an instance of the Formatter class, I'd need to pass an instance of a IConfigService implementation (which is expensive and cumbersome, because it would require different xml files and takes a while). My problem here is that I don't want to create an instance of the configService for every unit test because this would mean that I'd test the configService itself with every test in the FormatterCore unit.
In order to test FormatterCore you should not create an instance of a IConfigService implementation. You have to create and set up a mock object of IConfigService.
[TestClass]
public class FormatterCoreTest
{
Mock<IConfigService> сonfigServiceMock;
[TestInitialize]
public void Init()
{
сonfigServiceMock = new Mock<IConfigService>();
}
[TestMethod]
public void Format()
{
// arrange
var input = /* input value */;
var id = /* id value */;
var сonfigServiceMock
.Setup(services => services.YourMethodToMock())
.Returnes(/* expected result or behaviour */);
// act
var target = new FormatterCore(сonfigServiceMock.Object);
var result = target.Format</* AnyType */>(input, id);
// assert
/* Your asserts */
result.Should().Be(/* expectred result */);
Assert.AreEqual /* expectred result */, result);
}
}
Are types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff nested and can't be tested or public and it is possible?
If it is possible to test types SomeStuffA, SomethingUserfull, SomeOtherStuff and SomeReallyUselessStuff then it is better to inject their instances into constructor of FormatterCore instead of creating them in the constructor.
public class FormatterCore : IFormatterInterfaceIWantToTest
{
ISomeStuffA something;
ISomethingUserfull somethingThatINeed;
ISomeOtherStuff somethingElse;
ISomeReallyUselessStuff somethingTotallyDifferent;
public FormatterCore(
ISomeStuffA someStuffA,
ISomethingUserfull somethingUserfull,
ISomeOtherStuff someOtherStuff,
ISomeReallyUselessStuff someReallyUselessStuff
)
{
this.something = someStuffA;
this.somethingThatINeed = somethingUserfull;
this.somethingElse = someOtherStuff;
this.somethingTotallyDifferent = someReallyUselessStuff;
//...
}
public T Format<T>(object input, string id)
{
// implementation of the interface I want to test
}
}
Let your IoC be responsible for instance creation.
It will be needed to create and setup mocks for all dependencies in every test.
As you can't access the private variables of the XML formatting class (other than hacking into the class by reflection), and you can't be certain of when the other classes are created, I don't think you can mock them in the way you'd like to. Having to hack into a class to access private variables or methods for testing is a code smell - it means you have hidden testable functionality that should be exposed.
So, to expose that functionality, it seems like your best course of action would be to inject factories that the XML formatting class uses to create these other classes. Your XML reader/parser mock would be passed to the Create methods, and you would return appropriate mocks of those classes for the XML formatting class to use.
Alternatively, you could treat the XML formatting class as you would in an integration test - accept that other classes will be created with your XML reader/parser mock as a parameter, and set up that mock to expect calls from them as well.
I have a strange trouble. I am not too familiar with Moq, being more a GUI guy. I tried to mock a factory method in my code. The factory looks like this, and returns a ISettings instance which does many IO Operations. I want it to return a memory only ISettings instance to accelerate my test.
public class SettingsFactory
{
internal ISettings mSettingsImpl;
internal virtual ISettings CreateOrGetSettings()
{
return mSettingsImpl ?? (mSettingsImpl = new XmlSettings());
}
}
and the mock is
var imocked = new Mock<SettingsFactory>() {CallBase = false};
imocked.Setup(x => x.CreateOrGetSettings()).Returns(new NonPersistingSettings());
var tryToSeeTheType = imocked.Object.CreateOrGetSettings();
the tryToSeeTheType is however XMLSettings and not NonPersistingSettings as I would expect. Stepping through results into the code shown me that it goes directly into the original factory method. Any suggestions what I do wrong here?
The "Object" property of a mocked object is not actually an instance of the class you are trying to mock.
The purpose of a mock is to be able to replace an object the method you are trying to test depends on.
Imagine that your SettingsFactory performs very expensive operations like for example accessing the network or a database or the file system. You do not want your test to access those expensive resources so you create a mock. I would be something like this:
public class ClassThatUsesSettingsFactory
{
private readonly SettingsFactory _settingsFactory;
public ClassThatUsesSettingsFactory(SettingsFactory settingsFactory)
{
_settingsFactory = settingsFactory;
}
public void MethodThatCallsSettingsFactory()
{
//... do something
var settings = _settingsFactory.CreateOrGetSettings();
//... do something
}
}
By doing this you are able to replace the SettingsFactory with a mock on your unit test like so:
[TestMethod]
public void MakeSureSettingsFactoryIsCalled()
{
var settingsFactoryMock = new Mock<SettingsFactory>();
settingsFactoryMock.Setup(f => f.CreateOrGetSettings(), Times.Once).Verifiable();
var subjectUnderTest = new ClassThatUsesSettingsFactory(settingsFactoryMock.Object);
subjectUnderTest.MethodThatCallsSettingsFactory();
settingsFactoryMock.Verify();
}
This unit test is basically only making sure that the method CreateOrGetSettings gets called once and only once when the MethodThatCallsSettingsFactory gets executed.
What Moq does is to create a different class with a different implementation of its virtual method that will, most likely, set a flag to true once it gets called and then check the value of that flag on the "Verify" method.
There is a lot to grasp here so I hope it is clear enough since you mentioned that you do not have a lot of experience with Moq.
I'm using a boilerplate implementation of Model-View-Presenter in an ASP.NET WebForms application. My View has two events of consequence, one that signals that the user has filled out enough fields on the domain model to initiate a duplication check, and the other is a regular Save event. My pseudo code looks like this:
public class ItemNewPresenter : PresenterBase<IItemNewView>
{
public IItemService Service { get; private set; }
public IItemNewView View { get; private set; }
public ItemNewPresenter(IItemService service, IItemNewView view)
{
Service = service;
View = view;
View.OnSave += DoItemSave;
View.OnItemIsDuplicateCheck+= DoItemIsDuplicateCheck;
}
private void DoItemIsDuplicateCheck(object sender, CheckItemDuplicateEventArgs e)
{
CheckForItemDuplication(e.Item);
}
private void CheckForItemDuplication(Item item){
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item), "This item already exists");
}
}
private void DoItemSave(object sender, SaveItemEventArgs e)
{
DoItemIsDuplicateCheck(this, e.ToItemDuplicateEventArgs());
Service.Save(e.Item);
}
}
Here's my test for ensuring that my presenter behaves properly when OnItemIsDuplicateCheck is raised from the view:
[Test]
public void presenter_checking_for_existing_item_should_call_redirect_if_found()
{
var service = new Mock<IItemService>();
var view = new Mock<IItemNewView>();
var presenter = new ItemNewPresenter (service.Object, view.Object);
var onCheckExistingHandler = view.CreateEventHandler <CheckItemDuplicateEventArgs>();
view.Object.OnExistingDenominatorCheck += onCheckExistingHandler;
var eventArgs = new CheckItemDuplicateEventArgs();
service.Setup(s => s.IsDuplicate(It.Is<CheckItemDuplicateEventArgs>(c => c.Equals(eventArgs)))).Returns(true);
onCheckExistingHandler.Raise(eventArgs);
view.Verify(v => v.RedirectWithNotification(It.IsAny<String>(), It.IsAny<string>()), Times.Once());
service.Verify();
}
For consistency, I would like to have the same duplicate check fired when the View raises the OnSave event. My question is around how I am supposed to write my test when one of the methods I want to verify (CheckForItemDuplication) is declared on the class under test. The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
[Test]
public void presenter_saving_item_should_check_for_dupe_and_save_if_not_one() {
//duplicate mocks/setups/asserts from duplicate check fixture
//additional mocks/setups/asserts to test save logic
}
I think TDD would suggest pulling this private method out into a separate class that collaborates with my Presenter and would be injected via DI. But adding another dependency to my Presenter for functionality that doesn't seem worthy of being a freestanding abstraction *and*represents an internal implementation detail of my Presenter seems...well...crazy. Am I way off base here? There must be some design pattern or refactoring I can apply that would avoid the need to turn a private method into a dependency.
What I have done sometimes, when confronted with this dilemma, is to extract the function, make an internal constructor with the object as argument, AND a public constructor without. The public ctor is forwarded to the internal with a new object such as:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
Thus, you can use the empty constructor from outside, and the other constructor for when you want to inject a stubbed argument for testpurposes. As long as the empty constructor only forwards the call without any logic of its own, you can still test it, like it has only one constructor.
I would go with testing the class as is by adding the duplicate setup code. Once that test is passing and you are confident all test cases are covered you can then refactor your test code to remove duplication.
You can move the dependencies (service and view) to private fields, then add a method to create the SUT:
private Mock<IItemService> _service;
private Mock<IItemNewView> _view;
private PresenterBase<IItemNewView> CreateSUT()
{
_service = new Mock<IItemService>();
_view = new Mock<IItemNewView>();
return new ItemNewPresenter (service.Object, view.Object);
}
(I think most people would prefer to initialize the Mock objects in the Setup method.)
Call the CreateSUT from your tests and now there is a little less duplication. Then you may want to add private method(s) for creating the event handler / raising the event as long as it is something that is being done the same or similar in more than one tests case.
Having this CreateSUT method cuts down on the amount of test code that is calling your constructor making it easier in the future if you were to add / remove / change dependencies. If you treat your test code like any other code and use the DRY principle when you see duplication it can result in more explicit, easier to read, maintainable test code. Dealing with very similar setup and test context is a common issue with unit testing and should not always change how the class being tested is/was designed.
I'll be interested if there are better answers, as I encounter this all the time.
The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
I'm not sure why you feel it makes the test less focused, but in your shoes I would do exactly what it sounds like you don't want to do--have duplicated setup code to test isolated cases for the SUT. You are testing the external behavior of the SUT with the test you supplied, which seems exactly right to me.
I am personally not a fan of exposing more than is necessary from a class and/or making behavior that should be the responsibility of the SUT into a dependency just to facilitate testing. The "natural boundry" of the class's responsibility should not be violated just because you want to test it.
It is easier to unit-test the calculation of the url than to unit-test that redirection has occured.
If i understood you corretly you want to test that the mvp-s CheckForItemDuplication() redirects to a certain url by raising
the view-mock-s OnItemIsDuplicateCheck event.
private void CheckForItemDuplication(Item item)
{
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item),
"This item already exists");
}
}
In my opinion you are doing to much.
What if you rewrite your code as
internal protected GetErrorUrlForItem(Item item)
{
if (Service.IsDuplicateItem(item))
{
return BuildItemUrl(item,
"This item already exists");
}
return null;
}
private void CheckForItemDuplication(Item item)
{
var result = GetErrorUrlForItem(item);
if (result != null)
{
View.RedirectWithNotification(result);
}
}
In the unittest just test the internal method GetErrorUrlForItem(). You have to use the InternalsVisibleTo attribute to allow accessing the internal method.
I have a class similar to the following:
public class MyProxy : ClientBase<IService>, IService
{
public MyProxy(String endpointConfiguration) :
base(endpointConfiguration) { }
public int DoSomething(int x)
{
int result = DoSomethingToX(x); //This passes unit testing
int result2 = ((IService)this).DoWork(x)
//do I have to extract this part into a separate method just
//to test it even though it's only a couple of lines?
//Do something on result2
int result3 = result2 ...
return result3;
}
int IService.DoWork(int x)
{
return base.Channel.DoWork(x);
}
}
The problem lies in the fact that when testing I don't know how to mock the result2 item without extracting the part that gets result3 using result2 into a separate method. And, because it is unit testing I don't want to go that deep as to test what result2 comes back as... I'd rather mock the data somehow... like, be able to call the function and replace just that one call.
Do you have a preference for mocking frameworks?
The Partial Mock feature in Rhino Mocks seems like it should do what you want.
You can't really do that. You have three choices:
Subclass MyProxy and override DoWork, which will require some fiddling to please the compiler
Mock the Channel property, which will require that it is settable in the base class
Move DoWork out into another class, pass it the Channel in the constructor, and mock that in your tests
Do the following:
Set up an IService property such as:
public IService MyService { get; set; }
Then you can do: int result2 = MyService.DoWork(x) as long as somewhere in the constructor or whatever you set MyService = this;
If you don't want to expose the property you can make it private or whatever and test it using accessors.
You can do it by using latest Microsoft Research project Moles
Once you get it running, you can do following
MMyProxy.DoWork32 = () => put your mock result here.
Remember to set moleBehavior to fall-through for the unmocked methods.
I believe that you have a design issue here, your IService.DoWork should most likely live in another class, it looks like just a thin wrapper on something else. Have you considered refactoring it?
Then if it lives in another class you don't need any special handling for mocking.