I'm trying to write a unit test for a class but the class has a Private variable initiated when the class is created..
public class OrderFormService : IOrderFormService
{
private readonly IOrderItems _orderItems;
private readonly string _orderStartingGroup;
// constructor
public OrderFormService(IOrderItems orderItems)
{
_orderItems = orderItems;
_orderStartingGroup = "Sales";
{
// Other Methods
}
I'm trying to write a unit test now and to test a method in this class and it utilises the variable _orderStartingGroup...
[TestFixture]
public class OrderFormServiceTests
{
private ITreatmentFormService _service;
private Mock<IOrderItems> _orderItems;
[SetUp]
public void SetUp()
{
_orderItems = new Mock<IOrderItems>();
_service = new OrderFormService(_orderItems);
}
}
Is it possible to set up the _orderStartingGroup in OrderFormServiceTest so it can be used in unit tests for testing some methods in OrderFormService? If so, how do I go about it? I've tried googling it but results keep talking about accessing private variables in the class you're testing but this isn't what I'm trying to do.
Thanks in advance :)
Well even if there is a way of setting private field directly from unit test method it’ll break an architectural principle or two..
There are a few ways of how to deal with this problem. The simplest solution would be to change the ctor signature by adding an optional parameter:
// constructor
public OrderFormService(IOrderItems orderItems, string orderStartingGroup = null)
{
_orderItems = orderItems;
_orderStartingGroup = orderStartingGroup ?? "Sales";
{
And use it in unit test:
[SetUp]
public void SetUp()
{
_orderItems = new Mock<IOrderItems>();
_service = new OrderFormService(_orderItems, “testValue”);
}
I think this might an indicator that you are doing something wrong. I would rather focus on public interfaces rather than testing internal implementation. If this somehow reflected in public interface there should be a way to set it via public interface or convention (say read from a config file).
But if you absolutely need to do that, you can consider following:
Use fabjan's answer
Set private field value with reflection
Make this private member as protected and create an derived test class.
Related
I have to write tests for existing code with xUnit. Here is a simplified problem I faced with:
using Xunit;
namespace XUnitTestProject1
{
public class UnitTest1
{
[Fact]
public void Test1()
{
GlobalHanler.StaticProperty = "some value";
}
[Fact]
public void Test2()
{
Assert.Null(GlobalHanler.StaticProperty);
}
}
public static class GlobalHanler
{
public static string StaticProperty;
}
}
GlobalHandler owns another object, both are static
When I run 2 tests together, Test2 fails because it can see the value that was set in Test1.
However, when I run Test2 separately, it succeeds.
My goal is to make 2 tests pass when they run together. I need somehow to reset global static property for each test separately, but I can't change the implementation of GlobalHandler
Setting StaticProperty in each test method seems not an option, because it will affect other tests running in parallel
In order to have testable code, you should first put the logic in a class that can be created as many times as needed and then use that class across your code by passing the reference.
Your production code can always use a singleton, but having no direct references to the singleton makes it testable.
Singletons and testing do not cohabit very well due to the possible side effects and unclear dependencies.
You should avoid using static. Instead of this, create a simple class and register it in your DI container as a singleton. Then you can test it easily.
Simple example:
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IQueueUrlProvider, QueueUrlProvider>()
.BuildServiceProvider();
Console.WriteLine(serviceProvider.GetService<IQueueUrlProvider>().QueueUrl);
}
public interface IQueueUrlProvider
{
string QueueUrl { get; }
}
public class QueueUrlProvider : IQueueUrlProvider
{
private readonly Lazy<string> _getQueueUrlLazy;
public string QueueUrl => _getQueueUrlLazy.Value;
public QueueUrlProvider()
{
_getQueueUrlLazy = new Lazy<string>(GetQueueUrl);
}
private string GetQueueUrl()
{
// get url here
return "your queue url";
}
}
}
https://dotnetfiddle.net/JjRh4q
I have a concrete class CalculatorService of which I want to test CalculateBuyOrder() method. CalculatorService has several dependencies injected through constructor parameters and CalculateBuyOrder() calls another method on the same service.
I need a mock of the class that
Can be created without parameterless constructor (i.e., automatically mocking the dependency tree).
Has all methods mocked (stubbed) by default, with the option of overriding and calling the real implementation on one (or several) methods.
It seems such an obvious and basic use case, but I can't seem to neither figure it out myself nor find the documentation that explains it. The furthest I've gotten is using AutoMocker for achieving 1., but 2. has me stumped.
public class CalculatorService
: ICalculatorService
{
private readonly IMainDbContext _db;
private readonly TradeConfig _tradeConfig;
private readonly MainConfig _config;
private readonly StateConfig _state;
private readonly ICurrencyService _currencyService;
private readonly IExchangeClientService _client;
// Parameters need to be mocked
public CalculatorService(MainDbContext db, TradeConfig tradeConfig, MainConfig config, StateConfig state, ICurrencyService currencyService, IExchangeClientService client)
{
this._db = db;
this._tradeConfig = tradeConfig;
this._config = config;
this._state = state;
this._currencyService = currencyService;
this._client = client;
}
// This needs to be tested
public async Task<OrderDto> CalculateBuyOrder(
String coin,
CoinPriceDto currentPrice,
Decimal owned,
IDictionary<TradeDirection, OrderDto> lastOrders,
OrderDto existingOrder = null,
TradeConfig.TradeCurrencyConfig tradingTarget = null,
Decimal? invested = null)
{
// ...
this.GetInvested();
// ...
}
// This needs to be mocked
public virtual IDictionary<String, Decimal> GetInvested()
{
// ...
}
}
}
As some of the comments have said you should place interfaces in your constructor as for an example pseudo code:
public class Foo : IFoo
{
IBoo boo;
IGoo goo;
public Foo(IBoo boo, IGoo goo)
{
this.boo = boo;
this.goo = goo;
}
public int MethodToTest(int num1,int num2)
{
//some code
/*..*/ = boo.Method(num1,num2);
//more code and return
}
}
notice all the parameters in the constructor are interfaces.
and then your test method would look a little like this
[TestMethod]
public void TestMethod()
{
//setting up test
var boo = new Mock<IBoo>();
var goo = new Mock<IGoo>();
var foo = new Foo(boo.object,goo.object);
boo.Setup(x=>x.Method(1,2)).Returns(10);
//running test
var result = foo.MethodToTest(1,2);
//verify the test
Assert.AreEqual(12,result);
}
For more information just go to this link Moq Github.
Now for the second part of your question, mocking a method within the same class. This defeats the purpose of mocking, as mocking is to "fake" dependencies. So either restructure the code so you can mock it properly, or make sure any methods it calls are mocked in a way they'll give a reliable output that you can use.
I'm using Typemock to do some unit testing. In my case Im writing tests for a program that does flat file dataprocessing. In order to unit test that program I've written a few stub classes which implement the same interface the actual version uses, but instead of writing to the file system, contain an internal string they write to.
Now I'm trying to get Typemock to replace the actual versions of the classes with the stub variants in tests, but it's giving me the following error:
System.InvalidOperationException : Nullable object must have a value.
This is the actual version I'm trying to replace with my stub (contains more but the error is not on those lines):
public class BatchRepository : IBatchRepository
{
private readonly string _connectionStringName;
public BatchRepository(string connectionStringName) <-- Error triggers on this line
{
_connectionStringName = connectionStringName;
}
}
The stub class:
public class BatchRepositoryStub : IBatchRepository
{
private readonly string _connectionStringName;
public BatchRepositoryStub(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
}
The test class and my testmethod:
[TestClass]
public class InputTest
{
// Variables
private IBatchRepository _batchRepository;
private ICommunicatieproductRepository _communicatieproductRepository;
// Constants
private const string ConnectionStringName = "Test";
private const string InputFileLocation = "Temp";
private const string ArchiefLocation = "Temp";
private const string ErrorLocation = "Temp";
private const string LoggingLocation = "Temp";
private const int BatchGrootte = 1000;
// Use TestInitialize to run code before running each test
[TestInitialize()]
public void Initialize()
{
_batchRepository = new BatchRepositoryStub(ConnectionStringName);
_communicatieproductRepository = new CommunicatieproductRepositoryStub(ConnectionStringName);
}
[TestMethod]
public void CMBatch_FDInput_NewFileErrorOnEmptyRelatienummer()
{
// Arrange
Isolate.Swap.NextInstance<IBatchRepository>().With(_batchRepository);
Isolate.Swap.NextInstance<ICommunicatieproductRepository>().With(_communicatieproductRepository);
var inputFileProcessor = new InputFileProcessor(InputFileLocation, ArchiefLocation, ErrorLocation, LoggingLocation, BatchGrootte, ConnectionStringName);
}
}
The actual process, this triggers the error
public class InputFileProcessor
{
private readonly string _inputFileLocation;
private readonly string _archiefLocation;
private readonly string _errorLocation;
private readonly string _loggingLocation;
private readonly int _batchGrootte;
private readonly IBatchRepository _batchRepository;
private readonly ICommunicatieproductRepository _communicatieproductRepository;
/// <summary>
/// Constructor
/// </summary>
public InputFileProcessor(string inputFileLocation, string archiefLocation, string errorLocation, string loggingLocation, int batchGrootte, string connectionStringName)
{
_inputFileLocation = inputFileLocation;
_archiefLocation = archiefLocation;
_errorLocation = errorLocation;
_loggingLocation = loggingLocation;
_batchGrootte = batchGrootte;
_batchRepository = new BatchRepository(connectionStringName);
_communicatieproductRepository = new CommunicatieproductRepository(connectionStringName);
}
}
The error triggers on the constructor of BatchRepository, when called from the constructor of InputFileProcessor. At first I thought the parameter connectionstringname was null, but this isn't the case. Why is it ending up on that line anyway? With the swap instance method, I presumed it would't even get there, but end up in the stub class. I think there something wrong with my implementation of swap instance, but I can't figure it out.
I know testing like this is probably not exactly what unit testing is about, but it's the easiest way to test the output and input of the program. For instance, I need to make sure that invalid files trigger the corresponding errors. Being able to easily change the input makes that a lot more manageable.
Of course this can be done with Typemock :-)
Use Swap.CallsOn(object) to forward calls to the stub (these don't need to be assignable).
see example:
// grab future
var futureInstanceHandle = Isolate.Fake.NextInstance<BatchRepository>();
// swap (ingoring type hiearchy)
Isolate.Swap.CallsOn(futureInstanceHandle).WithCallsTo(_batchRepositorystub);
In version 8, you can use Fake.NextInstance<IBatchRepository> for interfaces! This will grab the first instance that implements IBatchRepository - pretty cool eh.
p.s I work at Typemock.
Apparently this is something that can't be done wth Typemock. It's essentially testing a too large chunck of code aswell, which isn't exactly unit testing.
Currently I've refactored the code with a variant that is used internally here at the company.
I'm really new to mocks and am trying to replace a private field with a mock object. Currently the instance of the private field is created in the constructor. My code looks like...
public class Cache {
private ISnapshot _lastest_snapshot;
public ISnapshot LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() {
this.LatestSnapshot = new Snapshot();
}
public void Freeze(IUpdates Updates) {
ISnapshot _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
What I'm trying to do is create a unit test that asserts ISnapshot.FreezeFrom(IUpdates) is called from within Cache.Freeze(IUpdates). I'm guessing I should replace the private field _latest_snapshot with a mock object (maybe wrong assumption?). How would I go about that while still retaining a parameterless constructor and not resorting to making LatestSnapshot's set public?
If I'm totally going about writing the test the wrong way then please do point out as well.
The actual implementation of ISnapshot.FreezeFrom itself calls a heirarchy of other methods with a deep object graph so I'm not too keen on asserting the object graph.
Thanks in advance.
I'm almost citing techniques from "Working Effectively with Legacy Code":
Sub-class your class in a unit test and supersede your private variable with a mock object in it (by adding a public setter or in the constructor). You probably have to make the variable protected.
Make a protected getter for this private variable, and override it in testing subclass to return a mock object instead of the actual private variable.
Create a protected factory method for creating ISnapshot object, and override it in testing subclass to return an instance of a mock object instead of the real one. This way the constructor will get the right value from the start.
Parametrize constructor to take an instance of ISnapshot.
I'm not sure that you can do that. If you're wanting to test _next then you're probably going to have to pass it in as a parameter and then in your unit test pass in a Mock object which you can then test using an Expectation. That's what I'd be doing if I were trying to do it in Moq.
As an example of what I might try using the Moq framework:
Mock<ISnapshot> snapshotMock = new Mock<ISnapshot>();
snapshotMock.Expect(p => p.FreezeFrom(expectedUpdate)).AtMostOnce();
Cache c = new Cache(snapshotMock.Object);
c.Freeze(expectedUpdate);
Note: I haven't tried to compile the above code. Its just there to give an example of how I'd approach solving this.
I don't think you'd need to mock private member variables. Isn't the whole idea of mocking that the public interface for an object works as expected? Private variables are implementation details that mocks aren't concerned with.
This answer might be simple, but looking at the code, is there any way in which ISnapshot.FreezeFrom(IUpdates) is not going to be called? Sounds like you want to assert something that will always be true.
As Jason says, mocking is meant for situations where your class depends on SomeInterface to do it's work, and you want to test YourClass in isolation from whichever implementation of SomeInterface you actually use at runtime.
The question to ask is: what are the externally visible effects if this worked?
What happens to all those Snapshots? One option might to initialise the Cache with its first Snapshot from outside, say in the constructor. Another might be to mock whatever it is that the Snapshot calls that matters outside the cache. It depends on what you care that happens.
It might be too late to respond. Anyways. I also had similar problem.
public class Model
{
public ISomeClass XYZ{
get;
private set;
}
}
I required to set value of XYZ in my test case. I resolved the problem using this syntex.
Expect.Call(_model.XYZ).Return(new SomeClass());
_repository.ReplayAll();
In the case above we can do it like this
Expect.Call(_cache.LatestSnapshot).Return(new Snapshot());
_repository.ReplayAll();
You will probably have to refactor your class like this, in order for it to be injected with a different dependency for ISnapshot. Your class will remain to function the same.
public class Cache {
private ISnapshot _lastest_snapshot;
public ISnapshot LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() : this (new Snapshot()) {
}
public Cache(ISnapshot latestSnapshot) {
this.LatestSnapshot = latestSnapshot;
}
public void Freeze(IUpdates Updates) {
ISnapshot _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
You can simply add "setSnapshot(ISnapshot)" method to the Cache with your mocked class instance.
You can also add a constructor that takes ISnapshot.
Turn Cache into a template as shown below.
template <typename T=ISnapshot>
public class Cache {
private T _lastest_snapshot;
public T LatestSnapshot {
get { return this._lastest_snapshot; }
private set { this._latest_snapshot = value; }
}
public Cache() {
this.LatestSnapshot = new Snapshot();
}
public void Freeze(IUpdates Updates) {
T _next = this.LastestSnapshot.CreateNext();
_next.FreezeFrom(Updates);
this.LastestSnapshot = _next;
}
}
In production code do:
Cache<> foo;//OR
Cache<ISnapshot> bar;
In test code do:
Cache<MockSnapshot> mockFoo;
I have an immutable class with some private fields that are set during the constructor execution. I want to unit test this constructor but I'm not sure the "best practice" in this case.
Simple Example
This class is defined in Assembly1:
public class Class2Test
{
private readonly string _StringProperty;
public Class2Test()
{
_StringProperty = ConfigurationManager.AppSettings["stringProperty"];
}
}
This class is defined in Assembly2:
[TestClass]
public class TestClass
{
[TestMethod]
public void Class2Test_Default_Constructor()
{
Class2Test x = new Class2Test();
//what do I assert to validate that the field was set properly?
}
}
EDIT 1: I have answered this question with a potential solution but I'm not sure if it's the "right way to go". So if you think you have a better idea please post it.
This example isn't really worth testing, but assume the constructor has some more complex logic. Is the best approach to avoid testing the constructor and to just assume it works if all the tests for the methods on the class work?
EDIT 2: Looks like I made the sample a little to simple. I have updated it with a more reasonable situation.
Nothing, unless you are using that field. You don't want over-specification via tests. In other words, there is no need to test that the assignment operator works.
If you are using that field in a method or something, call that method and assert on that.
Edit:
assume the constructor has some more complex logic
You shouldn't be performing any logic in constructors.
Edit 2:
public Class2Test()
{
_StringProperty = ConfigurationManager.AppSettings["stringProperty"];
}
Don't do that! =) Your simple unit test has now become an integration test because it depends on the successful operation of more than one class. Write a class that handles configuration values. WebConfigSettingsReader could be the name, and it should encapsulate the ConfigurationManager.AppSettings call. Pass an instance of that SettingsReader class into the constructor of Class2Test. Then, in your unit test, you can mock your WebConfigSettingsReader and stub out a response to any calls you might make to it.
I have properly enabled [InternalsVisibleTo] on Assembly1 (code) so that there is a trust relationship with Assembly2 (tests).
public class Class2Test
{
private readonly string _StringProperty;
internal string StringProperty { get { return _StringProperty; } }
public Class2Test(string stringProperty)
{
_StringProperty = stringProperty;
}
}
Which allows me to assert this:
Assert.AreEqual(x.StringProperty, "something");
The only thing I don't really like about this is that it's not clear (without a comment) when you are just looking at Class2Test what the purpose of the internal property is.
Additional thoughts would be greatly appreciated.
In your edit, you now have a dependancy on ConfigurationManager that is hard to test.
One suggestion is to extract an interface to it and then make the Class2Test ctor take an IConfigManager instance as a parameter. Now you can use a fake/mock object to set up its state, such that any methods that rely on Configuration can be tested to see if they utilize the correct values...
public interface IConfigManager
{
string FooSetting { get; set; }
}
public class Class2Test
{
private IConfigManager _config;
public Class2Test(IConfigManager configManager)
{
_config = configManager;
}
public void methodToTest()
{
//do something important with ConfigManager.FooSetting
var important = _config.FooSetting;
return important;
}
}
[TestClass]
public class When_doing_something_important
{
[TestMethod]
public void Should_use_configuration_values()
{
IConfigManager fake = new FakeConfigurationManager();
//setup state
fake.FooSetting = "foo";
var sut = new Class2Test(fake);
Assert.AreEqual("foo", sut.methodToTest());
}
}