2010-02-17 36 views
7

Tôi có phương pháp này phụ thuộc vào ngày hiện tại. Nó sẽ kiểm tra nếu ngày hôm nay là Sun, Mon, Tue hoặc Wed, sau đó nó cung cấp cho 5 ngày của thời gian dẫn cho sự xuất hiện của các mặt hàng vận chuyển. Nếu Thur, Fri hoặc Sat của nó sau đó nó cung cấp cho 6 ngày của thời gian dẫn đến tài khoản cho cuối tuần.Cách kiểm tra logic phụ thuộc vào ngày hiện tại

private DateTime GetEstimatedArrivalDate() 
{ 
    DateTime estimatedDate; 
    if (DateTime.Now.DayOfWeek >= DayOfWeek.Thursday) 
    { 
     estimatedDate = DateTime.Now.Date.AddDays(6); 
    } 
    else 
    { 
     estimatedDate = DateTime.Now.Date.AddDays(5); 
    } 
    return estimatedDate; 
} 

Logic ước tính thực tế phức tạp hơn. Tôi đã đơn giản hóa nó cho mục đích của câu hỏi này. Câu hỏi của tôi là làm thế nào để viết một bài kiểm tra đơn vị cho một cái gì đó như thế này mà phụ thuộc vào ngày todays?

+0

Câu trả lời là (hầu như) trong câu hỏi "làm thế nào để viết một bài kiểm tra đơn vị cho một cái gì đó như thế này mà phụ thuộc vào ngày todays?" Tái cấu trúc phương pháp để sử dụng tiêm phụ thuộc như trong câu trả lời của Mark. –

Trả lời

17

Bạn cần phải vượt qua ngày tháng hiện tại như một tham số:

private DateTime GetEstimatedArrivalDate(DateTime currentDate) 
{ 
    DateTime estimatedDate; 
    if (currentDate.DayOfWeek >= DayOfWeek.Thursday) 
    { 
     estimatedDate = currentDate.AddDays(6); 
    } 
    else 
    { 
     estimatedDate = currentDate.AddDays(5); 
    } 
    return estimatedDate; 
} 

Trong mã thực bạn gọi nó như thế này:

DateTime estimatedDate = GetEstimatedArrivalDate(DateTime.Now.Date); 

Sau đó, bạn có thể kiểm tra nó như sau:

DateTime actual = GetEstimatedArrivalDate(new DateTime(2010, 2, 10)); 
DateTime expected = ...; 
// etc... 

Lưu ý rằng điều này cũng khắc phục lỗi tiềm ẩn trong chương trình của bạn nơi ngày thay đổi giữa các cuộc gọi liên tiếp thành DateTime.Now.

+0

Tôi vừa đăng câu trả lời tương tự. Bạn đánh bại tôi với tốc độ :) – Romain

+0

cố định nếu cho bạn. –

+1

+1 cho dòng cuối cùng ... –

0

Dường như số lượng trường hợp đủ giới hạn mà bạn có thể kiểm tra từng trường hợp một cách rõ ràng. Phương pháp này phụ thuộc vào ngày hôm nay, nhưng đầu ra chỉ phụ thuộc vào ngày trong tuần và mỗi ngày có một ngày trong tuần.

0

Bạn có thể chuyển cho người đại diện trả về DateTime.Now trong quá trình thực hiện bình thường và sau đó trong thẻ thử nghiệm của bạn trong một đại biểu khác trả về ngày cố định và xác nhận kết quả của bạn dựa trên đó.

0

Một cách "phổ biến" để làm như vậy là "giả" ngày hệ thống hiện tại (có thể được thực hiện theo nhiều cách) và sau đó kiểm tra mã của bạn vào các ngày "đã biết".

Một cách thú vị là thay đổi thực hiện bạn một chút để:

private DateTime GetEstimatedArrivalDate() 
{ 
    return GetEstimatedArrivalDate(DateTime.Now); 
} 

private DateTime GetEstimatedArrivalDate(DateTime forDate) 
{ 
    DateTime estimatedDate; 
    if (forDate.DayOfWeek >= DayOfWeek.Thursday) 
    { 
     estimatedDate = forDate.Date.AddDays(6); 
    } 
    else 
    { 
     estimatedDate = forDate.Date.AddDays(5); 
    } 
    return estimatedDate; 
} 

Và sau đó sử dụng phương pháp này với một tham số để kiểm tra vào những ngày "ngay lập tức".

1

Tôi sẽ đưa ra câu trả lời gây tranh cãi, đừng thử nghiệm nó.

Logic là tầm thường và nó không phụ thuộc, tôi tin vào phạm vi mã tốt nhưng không phải khi nó làm tăng độ phức tạp để không đạt được thực.

+1

Nghe có vẻ hợp lý, nhưng đây chính là loại phương pháp mà tôi mong đợi sẽ thay đổi bất ngờ. Nếu công ty thay đổi chính sách giao hàng của họ, hãy bắt đầu cung cấp dịch vụ theo cấp hoặc chuyển nhà cung cấp dịch vụ. Bây giờ về mặt kỹ thuật, bạn có thể bắt đầu thử nghiệm nó một khi nó trở nên phức tạp, nhưng tôi có xu hướng nghĩ rằng đây là một bản lề quan trọng trong ứng dụng, và nó phải được kiểm tra để hoàn toàn mọi người biết thời điểm nó thay đổi. Chỉ trong trường hợp. – jcdyer

+0

Bah. Điều gì xảy ra nếu chúng tôi quyết định đổi vị trí thứ Năm và thứ Sáu trong tuần? Bạn sẽ không bao giờ biết mã này đã bị hỏng * cho đến khi nó đã quá trễ! * Và nếu chúng tôi quyết định bắt đầu đếm ngày * lạc hậu *, tốt, sau đó, tôi thậm chí không biết * những gì * để cho bạn biết nếu bạn có thể không hiển thị cho tôi đèn đỏ "thử nghiệm thất bại" nhấp nháy. ;) – Aaronaught

+0

Tôi đồng ý với những người nhận xét khác. Logic trong phương pháp này thực sự không phải là trival. Tôi đã làm cho nó đơn giản chỉ cho mục đích hiển thị nó như là một ví dụ cho câu hỏi của tôi. Tôi muốn kiểm tra kỹ lưỡng. –

9

Nói chung, bạn muốn để tóm tắt các phương pháp thu thập ngày hiện tại và thời gian đằng sau một giao diện, ví dụ:

public interface IDateTimeProvider 
{ 
    DateTime Now { get; } 
} 

Các dịch vụ thực sẽ là:

public class DateTimeProvider: IDateTimeProvider 
{ 
    public DateTime Now 
    { 
     get 
     { 
      return DateTime.Now; 
     } 
    } 
} 

Và một dịch vụ kiểm tra sẽ là:

public class TestDateTimeProvider: IDateTimeProvider 
{ 
    private DateTime timeToProvide; 
    public TestDateTimeProvider(DateTime timeToProvide) 
    { 
     this.timeToProvide = timeToProvide; 
    } 

    public DateTime Now 
    { 
     get 
     { 
      return timeToProvide; 
     } 
    } 
} 

Đối với các dịch vụ yêu cầu thời gian hiện tại, hãy yêu cầu IDa teTimeProvider là một phụ thuộc. Đối với điều thực, vượt qua một DateTimeProvider mới(); khi bạn là một thành phần, hãy vượt qua một TestDateTimeProvider mới (timeToTestFor).

+1

Tôi sẽ cung cấp cho bạn một + 1because của bạn hoàn toàn đúng nhưng cùng một lúc tôi cảm thấy nó là một chút trên đầu chỉ để thử nghiệm một phương pháp trival. Tôi ngưỡng mộ sự cống hiến của bạn để bảo hiểm mặc dù, và tôi có lẽ sẽ áp dụng điều này nếu có rất nhiều phương pháp hoặc một số phương pháp phức tạp cần kiểm tra :) –

+0

Nó có thể là tầm thường bây giờ, nhưng mọi thứ có thể dễ dàng thay đổi. Dù sao, 1 như tôi chắc chắn sẽ làm cho một bộ chuyển đổi xung quanh lớp DateTime để cho phép thử nghiệm. Thêm vào đó, đối với một TDDer, đây sẽ là con đường bình thường. – Finglas

+0

Trên một lưu ý phụ, nó sẽ không tốt hơn để sử dụng một khuôn khổ mocking, thay vì tạo ra một "dịch vụ thử nghiệm" mà bây giờ bạn cần phải duy trì là tốt? Có vẻ như một chút không đồng đều? –

2

Make lớp học của bạn có một IClock tham số (thông qua constructor hoặc tài sản)

interface IClock 
{ 
    DateTime Now { get; } 
} 

Sau đó bạn có thể sử dụng một thi giả để thử nghiệm

class FakeClock : IClock 
{ 
    DateTime Now { get; set } 
} 

và thực hiện thực phần còn lại của thời gian.

class SystemClock : IClock 
{ 
    DateTime Now { get { return DateTime.Now; } } 
} 
0

tôi sẽ đề nghị làm điều này như Mark suggests, nhưng với việc bổ sung của một cuộc gọi quá tải để sử dụng sản xuất mà mất không tham số và sử dụng DateTime.Now

private DateTime GetEstimatedArrivalDate() 
{ 
    return GetEstimatedArrivalDate(DateTime.Now); 
} 

private DateTime GetEstimatedArrivalDate(DateTime currentDate) 
{ 
    DateTime estimatedDate; 
    if (currentDate.DayOfWeek >= DayOfWeek.Thursday) 
    { 
     estimatedDate = currentDate.AddDays(6); 
    } 
    else 
    { 
     estimatedDate = currentDate.AddDays(5); 
    } 
    return estimatedDate; 
} 
Các vấn đề liên quan