1

I am trying to write a unit test for My Processor class I have two problems

  • I do not know how to test my Methods Only. this is my processor


OrderProcessor class

 public class OrderProcessor { public void Process(CustomersOrder order) { var oldOrder = _repository.GetOldorderId(order.Code.Value); if (oldOrder != 0) { updateOrder(order); } else { SaveOrder(order); } } private void updateOrder(CustomersOrder order) { _repository.UpdateOrder(order); } private void SaveOrder(CustomersOrder order) { _repository.SaveOrder(order); } } } 

Repository class

 public class Repository : IRepository { private static PracticeEntities4 _context; public Repository(PracticeEntities4 context) { _context = context; } public int GetOldCustomerId( int customerCode) { var CuID= _context.Customers.First(e => e.Code == customerCode); return CuID.Id; } public int GetOldorderId(int orderCode) { var oldOrder = _context.CustomersOrders.FirstOrDefault(e => e.Code == orderCode); return oldOrder.Id; } public void SaveCustomer(Customer customer) { _context.Customers.Add(customer); _context.SaveChanges(); } public void SaveOrder(CustomersOrder order) { _context.CustomersOrders.Add(order); _context.SaveChanges(); } public void UpdateOrder(CustomersOrder order) { _context.CustomersOrders.AddOrUpdate(order); _context.SaveChanges(); } } 

and this is My unit test I don't know how to fix it and where is the problem exactly and also I want to test the Methods too.

UnitTests Class

 [TestClass] public class OrderProcessorTest { [ClassInitialize] {...} [TestInitialize] public void TestInitialize() { .... } [TestMethod] public void Customer_OrderProcess() { //Arange Mock<IRepository> mock= new Mock<IRepository>(); //Act mock.Setup(e => e.GetOldCustomerId(1001)).Returns(3); mock.Setup(e => e.GetOldStoreId(200)).Returns(3); var dtos = OrderDeserializer.Deserialize(path); var dto = dtos.First(e => e.Code == 300); OrderBuilder builder = new OrderBuilder(mock.Object); builder.OrderBuild(dto); //Asset Assert.AreEqual(0, _orders.Count); } } 

Order Builder Class

public class OrderBuilder { public IRepository _repository { get; set; } public OrderBuilder(IRepository repository) { _repository = repository; } public CustomersOrder OrderBuild(OrderDto dto) { var oldStoreId = _repository.GetOldStoreId(dto.StoreCode); var oldCustomerId = _repository.GetOldCustomerId(dto.CustomerCode); return new CustomersOrder() { OrderDate = Convert.ToDateTime(dto.OrderDate), OrderStatus = dto.OrderStatus, DeliveryDate = Convert.ToDateTime(dto.DeliveryDate), CustomerId = oldCustomerId, StoreId = oldStoreId, Code = dto.Code }; } } 
3
  • 2
    Hi Nazaning, Its usually hard for people to review large code, I would suggest to reduce your question to an extend where it can be easily replicated. Commented Feb 2, 2020 at 7:45
  • thank you I did what you said hope this is better now. Commented Feb 2, 2020 at 7:59
  • @Nazanin The question in its current state is incomplete and therefore unclear. It would be awesome if you could reformat the question with a minimal reproducible example so we get a clearer picture of the current problem and what you are actually trying to do? See the How to Ask page for help clarifying this question. Commented Feb 2, 2020 at 12:00

2 Answers 2

1

In your code I see that there are all sorts of Mocking and Initial test setups that is taking place without a clear intention on what to test.

Unit Test: What ?

Tests a unit of an application without its external dependencies

Unit Test: Why ?

Makes refactoring faster and ensures you don't break existing portion of your code

Unit Test: Steps ?

  • We first need to re-factor the code before we do unit tests. Modularity is the key
  • By using Interfaces remove the tight couplings in the code
  • Inject the dependency via method parameters, constructor, properties or use Dependency Injection
  • Consider using Mock objects, as a good practice, only when dealing with external dependency.
  • In the [TestMethod] we organize the tests into 3 categories Arrange -> Act -> Assert

    Example:

    //Arrange var res = new Reservation(); //Act var op = res.Method(new User{IsAdmin=true}); // Assert Assert.IsTrue(op); 

Naming Conventions in UnitTests:

TestProjectName:     [InserProjectName].UnitTests
TestClasses:
        [InsertClassName]Tests
TestMethod:         [MethodYourTesting]_[Scenario]_[ExpectedBehavior]


I have created a Console app as close as possible to your problem (minus the DBContext) that you can replicate on your PC to understand the various portions.
All the domain classes are part of one single file for the sake of testability to reproduce faster.


Console App Project

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StackOrderProcessor { public class CustomersOrder { public OrderDto Order { get; set; } public List<CustomersOrder> CustomersOrders = new List<CustomersOrder>(); public DateTime OrderDate { get; set; } public string OrderStatus { get; set; } public int CustomerID { get; set; } public int Code { get; set; } public int ID { get; set; } } public class Customer { public OrderDto Order { get; set; } public List<Customer> Customers = new List<Customer>(); public int Code { get; set; } public int ID { get; set; } } public class OrderDto { public DateTime OrderDate { get; set; } public int CustomerCode { get; set; } public string OrderStatus { get; set; } public int Code { get; set; } } public interface IRepository { int GetOldCustomerId(int customerCode); int GetOldOrderId(int orderCode); void SaveCustomer(Customer customer); void SaveOrder(CustomersOrder order); } public class Repository : IRepository { private readonly Customer _cust; private readonly CustomersOrder _custOrder; public Repository(Customer cust, CustomersOrder custOrder ) { _cust = cust; _custOrder = custOrder; } public int GetOldCustomerId(int customerCode) { var cuId = _cust.Customers.First(e => e.Code == customerCode); return cuId.ID; } public int GetOldOrderId(int orderCode) { var oId = _custOrder.CustomersOrders.FirstOrDefault(e => e.Code == orderCode); return oId.ID; } public void SaveCustomer(Customer customer) { _cust.Customers.Add(customer); } public void SaveOrder(CustomersOrder order) { _custOrder.CustomersOrders.Add(order); } } public class OrderProcess { private readonly IRepository _repository; public OrderProcess(IRepository repository) { _repository = repository; } public void Process(CustomersOrder order) { var oldOrder = _repository.GetOldOrderId(order.Code); if (oldOrder == 0) _repository.SaveOrder(order); } } public class OrderBuilder { private readonly IRepository _repository; public OrderBuilder(IRepository repository) { _repository = repository; } public CustomersOrder OrderBuild(OrderDto dto) { var oldCustomerId = _repository.GetOldCustomerId(dto.CustomerCode); return new CustomersOrder() { Order = dto, OrderDate = Convert.ToDateTime(dto.OrderDate), OrderStatus = dto.OrderStatus, ID = oldCustomerId, CustomerID = oldCustomerId, Code = dto.Code }; } } class Program { static void Main(string[] args) { var cust = new Customer(); var custOrder = new CustomersOrder(); #region PopulatingCustomer //Populating OrderDto var dto1 = new OrderDto { Code = 1, CustomerCode = 1, OrderDate = DateTime.Now.Date, OrderStatus = "OK" }; //Populating Customer var customerList = cust.Customers = new List<Customer>(); var customerOrderList = custOrder.CustomersOrders = new List<CustomersOrder>(); var customer1 = new Customer { Code = 1, ID = 1, Order=dto1 }; var customer2 = new Customer { Code = 2, ID = 2, }; customerList.Add(customer1); customerList.Add(customer2); #endregion #region PopulatingCustomerOrder var customersOrder1 = new CustomersOrder { Code = 1, CustomerID = 1, ID = 1, Order = dto1, OrderDate = dto1.OrderDate, OrderStatus = dto1.OrderStatus }; customerOrderList.Add(customersOrder1); #endregion #region InvokingMethods //IRepository IRepository IRepo = new Repository(cust,custOrder); //OrderProcessor var orderProcesor = new OrderProcess(IRepo); //OrderBuilder var dto2 = new OrderDto { Code = 2, CustomerCode = 2, OrderDate = DateTime.Now.Date, OrderStatus = "OK" }; var oBuilder = new OrderBuilder(IRepo); var newCustOrder = oBuilder.OrderBuild(dto2); customerOrderList.Add(newCustOrder); #endregion Console.Read(); } } } 

UnitTest Project

using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using StackOrderProcessor; namespace StackOrderProcessor.UnitTests { [TestClass] public class RepositoryTests { [TestMethod] public void GetOldCustomerId_WhenCalled_ReturnsOId() { //Arrange var cust = new Customer(); var custOrder = new CustomersOrder(); IRepository repo = new Repository(cust,custOrder); var customerList = cust.Customers = new List<Customer>(); var dto1 = new OrderDto { Code = 1, CustomerCode = 1, OrderDate = DateTime.Now.Date, OrderStatus = "OK" }; var customer1 = new Customer { Code = 1, ID = 1, Order = dto1 }; var customer2 = new Customer { Code = 2, ID = 2, }; customerList.Add(customer1); customerList.Add(customer2); //Act repo.GetOldCustomerId(1); //Assert Assert.AreEqual(1, 1); //Test will Pass as we have a customer of Code 1 } [TestMethod] //MethodName_Scenario_Expectedbehavior public void SaveCustomer_WhenCalled_AddsNewCustomer() { var cust = new Customer(); var custOrder = new CustomersOrder(); IRepository repo = new Repository(cust, custOrder); var customerList = cust.Customers = new List<Customer>(); var dto1 = new OrderDto { Code = 1, CustomerCode = 1, OrderDate = DateTime.Now.Date, OrderStatus = "OK" }; var customer1 = new Customer { Code = 1, ID = 1, Order = dto1 }; var customer2 = new Customer { Code = 2, ID = 2, }; customerList.Add(customer1); customerList.Add(customer2); //Act var custToSave = new Customer { Code = 3, ID = 3, Order = null }; repo.SaveCustomer(custToSave); //Assert Assert.AreEqual(3, customerList.Count); } } [TestClass] public class OrderProcessor1Tests { [TestMethod] public void Process_WhenOrderIsZero_AddsNewCustomerOrder() { //Arrange var cust = new Customer(); var custOrder = new CustomersOrder(); var customerOrderList = custOrder.CustomersOrders = new List<CustomersOrder>(); IRepository repo = new Repository(cust, custOrder); var orderProcessor = new OrderProcess(repo); var dto1 = new OrderDto { Code = 1, CustomerCode = 1, OrderDate = DateTime.Now.Date, OrderStatus = "OK" }; var custOrder1 = new CustomersOrder { ID = 1, Code = 1, CustomerID = 1, Order = dto1, OrderDate = dto1.OrderDate, OrderStatus = dto1.OrderStatus }; customerOrderList.Add(custOrder1); //Act orderProcessor.Process(custOrder1); //Assert Assert.AreEqual(1, customerOrderList.Count); } } } 


Note: Make sure to add reference of StackOrderProcessor in StackOrderProcessor.UnitTests

enter image description here

You will still need to better organize the Unit Test Methods, this was just for demonstration purposes, I hope concepts are much more clear now

Sign up to request clarification or add additional context in comments.

Comments

0

Your question doesn't have enough information, you don't need your repository code for this question, but OrderBuiler class and _orders field needs. I'm sorry for this comment in answers location.

1 Comment

- Sure, I'll try

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.